Linux——等待队列

来源:互联网 发布:摄像头改网络编码器 编辑:程序博客网 时间:2024/06/08 13:09

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_EXCLUSIVE0x01void *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.超时唤醒]

0 0
原创粉丝点击