Linux内核--wait_queue_head机制流程简介

wait.h
/*

  • A single wait-queue entry structure:
    */
    struct wait_queue_entry {
    unsigned int flags;
    void *private;
    wait_queue_func_t func;
    struct list_head entry;
    };

struct wait_queue_head {
spinlock_t lock;
struct list_head head;
};
typedef struct wait_queue_head wait_queue_head_t;

/*

  • Macros for declaration and initialisaton of the datatypes
    */

#define __WAITQUEUE_INITIALIZER(name, tsk) {
.private = tsk,
.func = default_wake_function,
.entry = { NULL, NULL } }

#define DECLARE_WAITQUEUE(name, tsk)
struct wait_queue_entry name = __WAITQUEUE_INITIALIZER(name, tsk)

#define __WAIT_QUEUE_HEAD_INITIALIZER(name) {
.lock = __SPIN_LOCK_UNLOCKED(name.lock),
.head = { &(name).head, &(name).head } }
1: /*定义struct wait_queue_head waiter */
#define DECLARE_WAIT_QUEUE_HEAD(name)
struct wait_queue_head name = __WAIT_QUEUE_HEAD_INITIALIZER(name)

2: 根据condition,进入/退出 wait_queue

wait.c
//wq_entry add in wq_head, return 0 or -ERESTARTSYS
long prepare_to_wait_event(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state)
{
unsigned long flags;
long ret = 0;

spin_lock_irqsave(&wq_head->lock, flags);
if (unlikely(signal_pending_state(state, current))) {
	/*
	 * Exclusive waiter must not fail if it was selected by wakeup,
	 * it should "consume" the condition we were waiting for.
	 *
	 * The caller will recheck the condition and return success if
	 * we were already woken up, we can not miss the event because
	 * wakeup locks/unlocks the same wq_head->lock.
	 *
	 * But we need to ensure that set-condition + wakeup after that
	 * can't see us, it should wake up another exclusive waiter if
	 * we fail.
	 */
	list_del_init(&wq_entry->entry);
	ret = -ERESTARTSYS;
} else {
	if (list_empty(&wq_entry->entry)) {
		if (wq_entry->flags & WQ_FLAG_EXCLUSIVE)
			__add_wait_queue_entry_tail(wq_head, wq_entry);  //in list tail
		else
			__add_wait_queue(wq_head, wq_entry);  //in list head
	}
	set_current_state(state);
}
spin_unlock_irqrestore(&wq_head->lock, flags);

return ret;

}
EXPORT_SYMBOL(prepare_to_wait_event);

int __sched autoremove_wake_function(struct wait_queue_entry *wq_entry,
unsigned int mode, int sync, void *key)
{
int ret = default_wake_function(wq_entry, mode, sync, key);

if (ret)
	list_del_init(&wq_entry->entry);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值