毕业论文开发语言企业开发JAVA技术.NET技术WEB开发Linux/Unix数据库技术Windows平台移动平台嵌入式论文范文英语论文
您现在的位置: 毕业论文 >> linux >> 正文

Linux设备驱动之semaphore机制分析

更新时间:2013-6-14:  来源:毕业论文

Linux设备驱动之semaphore机制
在Linux系统中,信号号是一种重要的加锁机制,特别在互斥型资源中,semaphore更能很好的工作。
1: semaphore结构体定义
在Linux2.6.35内核中,semaphore的实现机制与以前的版本一点不同,在其中去除了DECLARE_MUTEX_LOCKED这个初始化互斥宏定义,但是,又添加了一个特别重要的函数,down_killable,这个函数的添加,使此版本的semaphore机制比以往的更强。semaphore结构全定义如下所示。

C/C++ code?123456 struct semaphore {     spinlock_t        lock;      /*  自旋锁结构体变量  */    unsigned int        count;     /*  用于计录资料数量  */    struct list_head    wait_list;   /*  内部链表结构体变量 */};  

从此结构体中可以看从,semaphore机制也就是自旋锁的包装,在后面的分析中,读者将会明白我为什么会这样说。
2: semaphore提供的操作函数
在semaphore机制中,系统给我们提供也几个函数用于操作,正因为内核给
我们提供了这些函数接口,我们才能应用其来更好的完成我们对互斥型资料的加锁,使其能准确无误的在SMP或者多线程中应用。semaphore提供接口函数如下所示。
 DECLARE_MUTEX
 init_MUTEX
 init_MUTEX_LOCKED
 down
 down_interruptible
 down_killable
 down_trylock
 down_timeout
 up

3 DECLARE_MUTEX接口分析
DECLARE_MUTEX接口为一个宏定义,此定义调用另一个宏定义来完成对
互斥型信号量进行初始化,其原型如下。

C/C++ code?123 #define DECLARE_MUTEX(name)    \     struct semaphore name = __SEMAPHORE_INITIALIZER(name, 1)

此宏用于初始化一个名为name的信号量,并把其资料数初始化为1。其中name为信号的名字,name为符合系统的标号,且不需提前定义。比如我们想定义一个名为my_semaphore的互斥型信号量,并把它初始化为1,我们将应用这个接口来实现,实现代码如下。

C/C++ code?1 DECLARE_MUTEX(my_semaphore);

从DECLARE_MUTEX宏义看出,此宏是通过调用另一个宏来实现的,此宏定义实现如下。

C/C++ code?1234567 #define __SEMAPHORE_INITIALIZER(name, n)                \ {                                    \     .lock        = __SPIN_LOCK_UNLOCKED((name).lock),        \     .count        = n,                        \     .wait_list    = LIST_HEAD_INIT((name).wait_list),        \ }

4 init_MUTEX接口分析
init_MUTEX接口用于动态初始化一个信号量,此接口也是一个宏定义,通
过调用sema_init函数来完成,此宏定义原型如下。

C/C++ code?12 #define init_MUTEX(sem)        sema_init(sem, 1)

其中sem为struct semaphore结构体变量,所以,在应用此宏来初始化一个信号前,必须定义一个struct semaphore结构体变量。此宏初始化一个名为sem的信号量,并把其资料初始化为1。
在此宏中我们看到,宏定义是通过调用sema_init函数来完成初始化的,所可,可以这样说,真正初始化sem信号量的应该是sema_init函数。为了读者方便查看,所以在此把sema_init函数的实现过程列出,关于此函数请读者自行查看\include\linux\semaphore.h文件,这样读者对semaphore的理解更加深入。sema_init函数实现如下。

C/C++ code?1234567 static inline void sema_init(struct semaphore *sem, int val) {     static struct lock_class_key __key;     *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val);     lockdep_init_map(&sem->lock.dep_map, "semaphore->lock", &__key, 0); }

5 init_MUTEX_LOCKED接口分析
init_MUTEX_LOCKED接口的实现与init_MUTEX接口的实现过程是一样的,
只是此接口把资源数初始化为0。所以在此不再进行分析,其实现如下。

C/C++ code?1 #define init_MUTEX_LOCKED(sem)    sema_init(sem, 0)

6 __down_common函数分析
在进行分析互斥信号量相关操作之前,进行分析一个特别重要的函数,因为
这个函数非常重要,semaphore的加锁操作都是基于这个函数实现的,所以,在分析它们之前进行分析这个函数,读者更加能看懂semaphore的实现过程。此函数的原型如下。

C/C++ code?12 static inline int __sched __down_common(struct semaphore *sem, long state,                                 long timeout)

在此函数中应用到的task_struct相关的知识,对于task_struct的知识在这个函数本人不进行分析,同时也不进行说明,因为task_struct机制是一个复杂的机制,不是三言两语就能分析的。在此函数中同样应用自旋锁的知识,关于自旋锁的知识本人将会在自旋锁机制相关的文章进行分析,在此文章中就不进行分析。本函数中一个重要的是超时调度,这一调度的实现如下。由于应用自旋锁加以保护,所以,超时调试过程有可中断,也不可中断,这就要看传入的state是允许中断还是不允许中断。超时调度实现过程如下。

C/C++ code?1 timeout = schedule_timeout(timeout);

7 down接口分析
down接口用于请求一个信号量。此函数的调用将会到致调用线程的睡眠,
直到获取到信号。同时,该函数的调用不允许中断。

[1] [2] 下一页

设为首页 | 联系站长 | 友情链接 | 网站地图 |

copyright©youerw.com 优尔论文网 严禁转载
如果本毕业论文网损害了您的利益或者侵犯了您的权利,请及时联系,我们一定会及时改正。