//将队列元素加入到等待队列头部设置非互斥等待
void add_wait_queue(wait_queue_head_t *q,
wait_queue_t *wait)
{
unsigned long flags;
/*
当一个等待队列入口有 WQ_FLAG_EXCLUSEVE 标志置位, 它被添加到等待队列的尾部. 没有这个标志的入口项, 相反, 添加 到开始
当 wake_up 被在一个等待队列上调用, 它在唤醒第一个有 WQ_FLAG_EXCLUSIVE 标志的进程后停止
*/
wait->flags &= ~WQ_FLAG_EXCLUSIVE;//设置为非互斥等待
//保存本地中断状态 关闭中断 获取自旋锁
spin_lock_irqsave(&q->lock, flags);
__add_wait_queue(q, wait); //将等待项,加入到等待队列头部
//回复本地中断状态 释放锁
spin_unlock_irqrestore(&q->lock, flags);
}
q:等待队列
wait:等待队列元素
头文件: #include <linux/wait.h>
static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
{
list_add(&new->task_list, &head->task_list);
}
//将等待元素加入到等待队列尾部 设置互斥等待
void add_wait_queue_exclusive(wait_queue_head_t *q,
wait_queue_t *wait)
{
unsigned long flags;
wait->flags |= WQ_FLAG_EXCLUSIVE;//设置为互斥等待
//保存本地中断状态 关闭中断 获取自旋锁
spin_lock_irqsave(&q->lock, flags);
//添加到队列尾部
__add_wait_queue_tail(q, wait);
//回复本地中断状态 释放锁
spin_unlock_irqrestore(&q->lock, flags);
}
q:等待队列
wait:等待队列元素
头文件: #include <linux/wait.h>
static inline void __add_wait_queue_tail(wait_queue_head_t *head,
wait_queue_t *new)
{
list_add_tail(&new->task_list, &head->task_list);
}
例子如下: