源码剖析之wait queue

wait queue

在内核中,一般使用等待队列(wait queue)实现当发生特定事件时的异步通知
具体方法如下:
1. 为每个特定的事件(可读、可写等)维护一个等待队列,本质上是一个双向链表
2. 关心该事件的实体作为等待队列中一项加入该等待队列中
3. 每个等待队列项包含关注该事件的实体的信息(进程、线程),以及回调函数
4. 当关注的事件发生时,会遍历相应的等待队列,调用每个节点中指定的回调函数

1. Structure

// wait_queue 头节点
typedef struct __wait_queue_head wait_queue_head_t;  
struct __wait_queue_head {  
    spinlock_t lock;  
    struct list_head task_list;  
};  

// wait_queue 节点  
typedef struct __wait_queue wait_queue_t;  
struct __wait_queue {  
    unsigned int flags;  
#define WQ_FLAG_EXCLUSIVE   0x01  
    void *private;  
    // 事件发生时的回调函数
    wait_queue_func_t func;  
    struct list_head task_list;  
};

// 回调函数的原型
typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key);  

2. Init

// include/linux/wait.h
extern void __init_waitqueue_head(wait_queue_head_t *q, const char *name, struct lock_class_key *);

#define init_waitqueue_head(q)              \
    do {                        \
        static struct lock_class_key __key; \
                            \
        __init_waitqueue_head((q), #q, &__key); \
    } while (0)

// /kernel/sched/wati.c
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);
}

// include/linux/list.h
static inline void INIT_LIST_HEAD(struct list_head *list)
{
    WRITE_ONCE(list->next, list);
    list->prev = list;
}


// include/linux/wait.h
static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
{
    q->flags    = 0;
    q->private  = p;
    q->func     = default_wake_function;
}

// include/linux/wait.h
static inline void
init_waitqueue_func_entry(wait_queue_t *q, wait_queue_func_t func)
{
    q->flags    = 0;
    q->private  = NULL;
    q->func     = func;
}

3. Add && Remove


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值