数据结构
1、等待队列由双向链表实现
2、每个等待队列都有一个等待队列头,等待队列头是一个类型位wait_queue_head_t的数据结构
typedef struct __wait_queue_head wait_queue_head_t;
struct __wait_queue_head {
spinlock_t lock; //同步自旋锁
struct list_head task_list; //等待进程链表的头
};
3、等待队列中的元素是wait_queue_t
typedef struct __wait_queue wait_queue_t;
struct __wait_queue {
unsigned int flags; //一般是用来标记是否为互斥进程
void *private; //一般用来保存等待的进程描述符
wait_queue_func_t func; //基本上作为唤醒函数地址
struct list_head task_list; //用于挂入链表头部的节点
};
操作函数
DECLARE_WAIT_QUEUE_HEAD 宏用于定义一个等待队列头
#define __WAIT_QUEUE_HEAD_INITIALIZER(name) { \
.lock = __SPIN_LOCK_UNLOCKED(name.lock), \ //初始化自旋锁,这里不展开
.task_list = { &(name).task_list, &(name).task_list } } //将队列头的的next、prev分别指向本身
#define DECLARE_WAIT_QUEUE_HEAD(name) \
wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
init_waitqueue_head用来初始化动态分配的等待队列头
#define init_waitqueue_head(q) \
do { \
static struct lock_class_key __key; \ //定义个key
\
__init_waitqueue_head((q), #q, &__key); \
} while (0)
void __init_waitqueue_head(wait_queue_head_t *q, const char *name, struct lock_class_key *key)
{
spin_lock_init(&q->lock); //初始化自旋锁
lockdep_set_class_and_name(&q->lock, key, name); //没有作用
INIT_LIST_HEAD(&q->task_list); //初始化队列头
}
函数init_waitqueue_entry 初始化wait_queue_t结构的变量q
static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
{
<