设备驱动技术实验五Word格式.docx

上传人:b****3 文档编号:6439486 上传时间:2023-05-06 格式:DOCX 页数:11 大小:128.08KB
下载 相关 举报
设备驱动技术实验五Word格式.docx_第1页
第1页 / 共11页
设备驱动技术实验五Word格式.docx_第2页
第2页 / 共11页
设备驱动技术实验五Word格式.docx_第3页
第3页 / 共11页
设备驱动技术实验五Word格式.docx_第4页
第4页 / 共11页
设备驱动技术实验五Word格式.docx_第5页
第5页 / 共11页
设备驱动技术实验五Word格式.docx_第6页
第6页 / 共11页
设备驱动技术实验五Word格式.docx_第7页
第7页 / 共11页
设备驱动技术实验五Word格式.docx_第8页
第8页 / 共11页
设备驱动技术实验五Word格式.docx_第9页
第9页 / 共11页
设备驱动技术实验五Word格式.docx_第10页
第10页 / 共11页
设备驱动技术实验五Word格式.docx_第11页
第11页 / 共11页
亲,该文档总共11页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

设备驱动技术实验五Word格式.docx

《设备驱动技术实验五Word格式.docx》由会员分享,可在线阅读,更多相关《设备驱动技术实验五Word格式.docx(11页珍藏版)》请在冰点文库上搜索。

设备驱动技术实验五Word格式.docx

1、实验内容与要求:

1)原子操作;

2)自旋锁;

3)信号量、互斥体机制。

2、实验安排方式:

采用1人1组,上机在Linux系统下进行编程实验。

三、实验设备

1、所用设备:

PC机一台

四、实验过程

所谓原子操作,就是该操作绝不会在执行完毕前被任何其他任务或事件打断,也就说,它的最小的执行单位,不可能有比它更小的执行单位,因此这里的原子实际是使用了物理学里的物质微粒的概念。

原子操作需要硬件的支持,因此是架构相关的,其API和原子类型的定义都定义在内核源码树的include/asm/atomic.h文件中,它们都使用汇编语言实现,因为C语言并不能实现这样的操作。

原子操作主要用于实现资源计数,很多引用计数(refcnt)就是通过原子操作实现的。

原子类型定义如下:

volatile修饰字段告诉gcc不要对该类型的数据做优化处理,对它的访问都是对内存的访问,而不是对寄存器的访问。

原子操作API包括:

0.该函数对原子类型的变量进行原子读操作,它返回原子类型的变量v的值。

1.该函数设置原子类型的变量v的值为i

atomic_set(atomic_t*v,inti);

2.该函数给原子类型的变量v增加值i。

voidatomic_add(inti,atomic_t*v);

3.该函数从原子类型的变量v中减去i。

atomic_sub(inti,atomic_t*v);

4.该函数从原子类型的变量v中减去i,并判断结果是否为0,如果为0,返回真,否则返回假。

intatomic_sub_and_test(inti,atomic_t*v);

5.该函数对原子类型变量v原子地增加1。

voidatomic_inc(atomic_t*v);

6.该函数对原子类型的变量v原子地减1

voidatomic_dec(atomic_t*v);

7.该函数对原子类型的变量v原子地减1,并判断结果是否为0,如果为0,返回真,否则返回假。

intatomic_dec_and_test(atomic_t*v);

8.该函数对原子类型的变量v原子地增加1,并判断结果是否为0,如果为0,返回真,否则返回假。

intatomic_inc_and_test(atomic_t*v);

9.该函数对原子类型的变量v原子地增加I,并判断结果是否为负数,如果是,返回真,否则返回假。

intatomic_add_negative(inti,atomic_t*v);

10.该函数对原子类型的变量v原子地增加i,并且返回指向v的指针。

intatomic_add_return(inti,atomic_t*v);

11.该函数从原子类型的变量v中减去i,并且返回指向v的指针。

intatomic_sub_return(inti,atomic_t*v);

12.该函数对原子类型的变量v原子地增加1并且返回指向v的指针。

intatomic_inc_return(atomic_t*v);

13.该函数对原子类型的变量v原子地减1并且返回指向v的指针。

intatomic_dec_return(atomic_t*v);

自旋锁原语要求的包含文件是<

linux/spinlock.h>

.一个实际的锁有类型spinlock_t.象任何其他数据结构,一个自旋锁必须初始化.这个初始化可以在编译时完成,如下:

spinlock_tmy_lock=SPIN_LOCK_UNLOCKED;

  或者在运行时使用:

voidspin_lock_init(spinlock_t*lock);

  在进入一个临界区前,你的代码必须获得需要的lock,用:

  voidspin_lock(spinlock_t*lock);

  注意所有的自旋锁等待是,由于它们的特性,不可中断的.一旦调用spin_lock,将自旋直到锁变为可用.

  为释放一个已获得的锁,传递它给:

  voidspin_unlock(spinlock_t*lock);

4个函数可以加锁一个自旋锁:

  voidspin_lock_irqsave(spinlock_t*lock,unsignedlongflags);

  voidspin_lock_irq(spinlock_t*lock);

  voidspin_lock_bh(spinlock_t*lock)

4个方法释放一个自旋锁

  voidspin_unlock_irqrestore(spinlock_t*lock,unsignedlongflags);

  voidspin_unlock_irq(spinlock_t*lock);

  voidspin_unlock_bh(spinlock_t*lock);

阻塞的自旋锁操作:

  intspin_trylock(spinlock_t*lock);

  intspin_trylock_bh(spinlock_t*lock);

2种方式被声明和被初始化:

  rwlock_tmy_rwlock=RW_LOCK_UNLOCKED;

/*Staticway*/

  rwlock_tmy_rwlock;

  rwlock_init(&

my_rwlock);

/*Dynamicway*/

为了记录可用资源的数量,需要一个count计数,标记当前可用资源数量。

需要一个count计数和等待进程的链表头即可。

描述信号量的结构体如下。

在linux中,需要一个结构体记录当前的进程信息(task_struct)。

structsemaphore_waiter的list成员是当进程无法获取信号量的时候挂入semaphore的wait_list成员。

task成员就是记录后续被唤醒的进程信息。

一切准备就绪,现在就可以实现信号量的申请函数。

(1).如果信号量标记的资源还有剩余,自然可以成功获取信号量。

只需要递减可用资源计数。

(2).既然无法获取信号量,就需要将当前进程挂入信号量的等待队列链表上。

(3).schedule()主要是触发任务调度的示意函数,主动让出CPU使用权。

在让出之前,需要将当前进程从运行队列上移除。

既然mutex是一种二值信号量,因此就不需要像semaphore那样需要一个count计数。

由于mutex具有“持锁者才能解锁”的特点,所以我们需要一个变量owner记录持锁进程。

释放锁的时候必须是同一个进程才能释放。

当然也需要一个链表头,主要用来便利睡眠等待的进程。

原理和semaphore及其相似,因此在代码上也有体现。

structmutex_waiter的list成员是当进程无法获取互斥量的时候挂入mutex的wait_list链表。

首先实现申请互斥量的函数。

(1).当mutex->

owner的值为0的时候,代表没有任何进程持有锁。

因此可以直接申请成功。

然后,记录当前申请锁进程的task_struct。

(2).既然不能获取互斥量,自然就需要睡眠等待,挂入等待链表。

互斥量的释放代码实现也同样和semaphore有很多相似之处。

(1).mutex具有“持锁者才能解锁”的特点就是在这行代码体现。

(2).如果等待链表没有进程,那么自然只需要将mutex->

owner置0,代表没有锁是释放状态。

(3).mutex->

owner的值改成当前可以持锁进程的task_struct。

(4).从等待进程链表取出第一个进程,并从链表上移除。

然后就是唤醒该进程。

五、程序清单

原子操作函数如下:

atomic_read(atomic_t*v);

自旋锁函数

voidspin_lock(spinlock_t*lock);

voidspin_unlock(spinlock_t*lock);

描述信号量的结构体

structsemaphore{

unsignedintcount;

structlist_headwait_list;

};

结构体记录当前的进程信息

structsemaphore_waiter{

structlist_headlist;

structtask_struct*task;

实现信号量的申请函数

voiddown(structsemaphore*sem)

{

structsemaphore_waiterwaiter;

if(sem->

count>

0){

sem->

count--;

 

/*1*/

return;

}

waiter.task=current;

/*2*/

list_add_tail(&

waiter.list,&

sem->

wait_list);

schedule();

/*3*/

}

两个类似的结构体分别描述mutex

structmutex_waiter{

structmutex{

longowner;

申请互斥量的函数

voidmutex_take(structmutex*mutex)

structmutex_waiterwaiter;

if(!

mutex->

owner){

mutex->

owner=(long)current;

/*1*/

互斥量的释放代码

intmutex_release(structmutex*mutex)

if(mutex->

owner!

=(long)current)/*1*/

return-1;

if(list_empty(&

wait_list)){

owner=0;

return0;

waiter=list_first_entry(&

wait_list,structmutex_waiter,list);

list_del(&

waiter->

list);

mutex->

owner=(long)waiter->

task;

wake_up_process(waiter->

task);

/*4*/

return0;

六、实验体会

(需要填写)

指导教师评语:

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2