1.数据结构
1.1等待队列头
1 struct __wait_queue_head { 2 spinlock_t lock; 3 struct list_head task_list; 4 }; 5 typedef struct __wait_queue_head wait_queue_head_t;
初始化等待队列头
1 #define __WAIT_QUEUE_HEAD_INITIALIZER(name) { \ 2 .lock = __SPIN_LOCK_UNLOCKED(name.lock), \ 3 .task_list = { &(name).task_list, &(name).task_list } } 4 5 #define DECLARE_WAIT_QUEUE_HEAD(name) \ 6 wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
1.2等待队列
1 typedef struct __wait_queue wait_queue_t; 2 typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int sync, void *key); 3 int default_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key); 4 5 struct __wait_queue { 6 unsigned int flags; 7 #define WQ_FLAG_EXCLUSIVE 0x01 8 void *private; 9 wait_queue_func_t func; 10 struct list_head task_list; 11 };
初始化等待队列
1 #define __WAITQUEUE_INITIALIZER(name, tsk) { \ 2 .private = tsk, \ 3 .func = default_wake_function, \ 4 .task_list = { NULL, NULL } } 5 6 #define DECLARE_WAITQUEUE(name, tsk) \ 7 wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk)
等待队列的task_list加入等待队列头的task_list链表。一般将wait_queue_func_t赋值为下面的默认处理函数:
1 int default_wake_function(wait_queue_t *curr, unsigned mode, int sync, 2 void *key) 3 { 4 return try_to_wake_up(curr->private, mode, sync); 5 }
1.3添加/删除等待队列
1 static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new) 2 { 3 list_add(&new->task_list, &head->task_list); 4 } 5 6 static inline void __remove_wait_queue(wait_queue_head_t *head, 7 wait_queue_t *old) 8 { 9 list_del(&old->task_list); 10 }
2等待事件
调用以下四个宏等待事件,等待以第一个参数作为等待队列头的等待队列被唤醒,第二个参数condition必须被满足,否则继续阻塞。
wait_event()和wait_event_interruptible()的区别是后者可以被信号打断,而前者不能。
加上timeout后的宏意味着阻塞等待的超时时间,以jiffy为单位,在timeout到达时,不论condition是否满足,均返回。
1 #define wait_event(wq, condition) 2 #define wait_event_timeout(wq, condition, timeout) 3 #define wait_event_interruptible(wq, condition) 4 #define wait_event_interruptible_timeout(wq, condition, timeout)
下面以wait_event()为例分析执行过程
1 #define wait_event(wq, condition) \ 2 do { \ 3 if (condition) \ 4 break; \ 5 __wait_event(wq, condition); \ 6 } while (0) 7 #define __wait_event(wq, condition) \ 8 do { \ 9 DEFINE_WAIT(__wait); \ 10 \ 11 for (;;) { \ 12 prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE); \ 13 if (condition) \ 14 break; \ 15 schedule(); \ 16 } \ 17 finish_wait(&wq, &__wait); \ 18 } while (0)