Linux——等待队列

1、等待队列头:wait_queue_head_t

struct __wait_queue_head {
	spinlock_t lock;
	struct list_head task_list;
};
typedef struct __wait_queue_head wait_queue_head_t;
》初始化等待队列头:
#define init_waitqueue_head(q)				\
	do {						            \
		static struct lock_class_key __key;	\
		__init_waitqueue_head((q), &__key);	\
	} while (0)
》__init_waitqueue_head 实现:
void __init_waitqueue_head(wait_queue_head_t *q, struct lock_class_key *key)
{
    spin_lock_init(&q->lock);
    lockdep_set_class(&q->lock, key);
    INIT_LIST_HEAD(&q->task_list); /* 循环链表实现 */
}
2、等待队列容器:wait_queue_t
typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key);
struct __wait_queue {
	unsigned int flags;
#define WQ_FLAG_EXCLUSIVE	0x01
	void *private;
	wait_queue_func_t func;
	struct list_head task_list;
};
typedef struct __wait_queue wait_queue_t;

》将当前进程current添加到等待队列容器中:

static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
{
    q->flags = 0;
    q->private = p; /* 当前进程PCB,赋值给等待队列容器的private */
    q->func = default_wake_function;
}

3、将包装好的等待队列容器添加到等待队列头所在的链表中:add_wait_queue

void add_wait_queue(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 (q, wait); /* list_add(&new->task_list, &head->task_list); */
    spin_unlock_irqrestore (&q->lock, flags);
}

4、设置当前进程状态:set_current_state

#define TASK_RUNNING0
#define TASK_INTERRUPTIBLE 1
#define TASK_UNINTERRUPTIBLE 2
5、将当前进程 current 添加到等待队列后,当前进程进入真正的睡眠,并开始调度任务:
schedule();
或 schedule_timeout(signed long timeout /* 5*HZ */);
6、改变当前任务状态并从等待队列中移除该进程:
   set_current_state (TASK_RUNNING);
   void remove_wait_queue (wait_queue_head_t *q/* 等待队列头 */, 
                            wait_queue_t *wait  /* 等待队列容器 */);
7、schedule() 返回后,判断返回条件:
1)schedule() 设备或者数据可读;
2)schedule_timeout() [a.设备或者数据可读][b.接收到中断信号][c.超时唤醒]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值