//用记事本分析的等待队列机制
static DECLARE_WAIT_QUEUE_HEAD(khubd_wait);//定义一个等待队列头
/*定义队列头分析*/
/**************************************************************************************/
struct list_head {
struct list_head *next, *prev;
};
struct __wait_queue_head {
spinlock_t lock;
struct list_head task_list;
};
typedef struct __wait_queue_head wait_queue_head_t;
/*初始化自旋锁和链表头*/
#define DECLARE_WAIT_QUEUE_HEAD(name) \
wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
#define __WAIT_QUEUE_HEAD_INITIALIZER(name) { \
.lock = __SPIN_LOCK_UNLOCKED(name.lock), \
.task_list = { &(name).task_list, &(name).task_list } }
/**************************************************************************************/
//hub驱动示例
wait_event_freezable(khubd_wait,!list_empty(&hub_event_list) || kthread_should_stop());
//跟踪调用链
#define wait_event_freezable(wq, condition) wait_event_interruptible(wq, condition)
//跟踪调用链
#define wait_event_interruptible(wq, condition) \
({ \
int __ret = 0; \
if (!(condition)) \//先判断下调节,看是否满足
__wait_event_interruptible(wq, condition, __ret); \
__ret; \
})
//继续跟踪调用链
#define __wait_event_interruptible(wq, condition, ret) \
do { \
DEFINE_WAIT(__wait); \//定义一个等待队列项
\
for (;;) { \
prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE); \
if (condition) \//再次判断条件是否满足
break; \
if (!signal_pending(current)) { \//判断是否有信号要处理?
schedule(); \//调度,睡眠
continue; \//唤醒后从该处继续执行?
} \
ret = -ERESTARTSYS; \
break; \
} \
finish_wait(&wq, &__wait); \
} while (0)
//分析DEFINE_WAIT()
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;
};
#define DEFINE_WAIT(name) DEFINE_WAIT_FUNC(name, autoremove_wake_function)
#define DEFINE_WAIT_FUNC(name, function) \
wait_queue_t name = { \//赋值为当前进程的描述符
.private = current, \//唤醒时执行函数
.func = function, \
.task_list = LIST_HEAD_INIT((name).task_list), \//用于链接到等待队列头
}
void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
{
unsigned long flags;
wait->flags &= ~WQ_FLAG_EXCLUSIVE;//把互斥标志清为0
spin_lock_irqsave(&q->lock, flags);
if (list_empty(&wait->task_list))
__add_wait_queue(q, wait);//加入到等待队列
set_current_state(state);//设置当前进程的状态
spin_unlock_irqrestore(&q->lock, flags);
}
static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
{
list_add(&new->task_list, &head->task_list);
}
/*唤醒的处理,以hub唤醒为例*/
static void kick_khubd(struct usb_hub *hub)
{
unsigned long flags;
spin_lock_irqsave(&hub_event_lock, flags);
if (!hub->disconnected && list_empty(&hub->event_list)) {
list_add_tail(&hub->event_list, &hub_event_list);//把等待的条件置为真
/* Suppress autosuspend until khubd runs */
usb_autopm_get_interface_no_resume(
to_usb_interface(hub->intfdev));
wake_up(&khubd_wait);//唤醒等待的进程
}
spin_unlock_irqrestore(&hub_event_lock, flags);
}
#define wake_up(x) __wake_up(x, TASK_NORMAL, 1, NULL)
void __wake_up(wait_queue_head_t *q, unsigned int mode, int nr_exclusive, void *key)
{
unsigned long flags;
spin_lock_irqsave(&q->lock, flags);
__wake_up_common(q, mode, nr_exclusive, 0, key);
spin_unlock_irqrestore(&q->lock, flags);
}
//唤醒nr_exclusive个排他性进程
static void __wake_up_common(wait_queue_head_t *q, unsigned int mode, int nr_exclusive, int wake_flags, void *key)
{
wait_queue_t *curr, *next;
list_for_each_entry_safe(curr, next, &q->task_list, task_list) {//取出队列的每一个等待项
unsigned flags = curr->flags;
//针对普通的先执行function函数,唤醒所有的非互斥等待节点和nr_exclusive个互斥节点
if (curr->func(curr, mode, wake_flags, key) &&(flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
break;
}
}
/*导致上面注册*/
int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key)
{
int ret = default_wake_function(wait, mode, sync, key);
if (ret)
list_del_init(&wait->task_list);//从等待队列中删除
return ret;
}
int default_wake_function(wait_queue_t *curr, unsigned mode, int wake_flags, void *key)
{
return try_to_wake_up(curr->private, mode, wake_flags);//唤醒等待的进程
}
//从睡眠的地方继续调度
void finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
{
unsigned long flags;
__set_current_state(TASK_RUNNING);//设置该进程的状态为TASK_RUNNING
if (!list_empty_careful(&wait->task_list)) {
spin_lock_irqsave(&q->lock, flags);
list_del_init(&wait->task_list);//从等待队列中删除
spin_unlock_irqrestore(&q->lock, flags);
}
}
//有两个函数分别是增加互斥和不互斥的节点
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);
spin_unlock_irqrestore(&q->lock, flags);
}
EXPORT_SYMBOL(add_wait_queue);
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);
}
//因为completion机制是基于等待队列的,所以在此一并分析
struct completion {
unsigned int done;
wait_queue_head_t wait;
};
init_completion(&us->scanning_done);
static inline void init_completion(struct completion *x)
{
x->done = 0;
init_waitqueue_head(&x->wait);
}
#define init_waitqueue_head(q) \
do { \
static struct lock_class_key __key; \
\
__init_waitqueue_head((q), &__key); \
} while (0)
//使用completion
wait_for_completion(&us->scanning_done);
void __sched wait_for_completion(struct completion *x)
{
wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE, 0);
}
static long __sched wait_for_common(struct completion *x, long timeout, int state, int iowait)
{
might_sleep();
spin_lock_irq(&x->wait.lock);
timeout = do_wait_for_common(x, timeout, state, iowait);
spin_unlock_irq(&x->wait.lock);
return timeout;
}
static inline long __sched do_wait_for_common(struct completion *x, long timeout, int state, int iowait)
{
if (!x->done) {//判断done是否为0
DECLARE_WAITQUEUE(wait, current);
__add_wait_queue_tail_exclusive(&x->wait, &wait);
do {
if (signal_pending_state(state, current)) {
timeout = -ERESTARTSYS;
break;
}
__set_current_state(state);//设置当前进程的状态
spin_unlock_irq(&x->wait.lock);
if (iowait)
timeout = io_schedule_timeout(timeout);
else
timeout = schedule_timeout(timeout);//调度,进入睡眠
spin_lock_irq(&x->wait.lock);
} while (!x->done && timeout);//看条件是否满足或者超时?
__remove_wait_queue(&x->wait, &wait);//从等待节点从队列中移除
if (!x->done)//如果不是done引起的唤醒,则返回超时时间
return timeout;
}
x->done--;//重新置为0
return timeout ?: 1;
}
#define __WAITQUEUE_INITIALIZER(name, tsk) { \
.private = tsk, \
.func = default_wake_function, \
.task_list = { NULL, NULL } }
#define DECLARE_WAITQUEUE(name, tsk) \
wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk)
//加入队列尾部
static inline void __add_wait_queue_tail_exclusive(wait_queue_head_t *q,
wait_queue_t *wait)
{
wait->flags |= WQ_FLAG_EXCLUSIVE;
__add_wait_queue_tail(q, wait);
}
complete(&us->scanning_done);
void complete(struct completion *x)
{
unsigned long flags;
spin_lock_irqsave(&x->wait.lock, flags);
x->done++;//done++
__wake_up_common(&x->wait, TASK_NORMAL, 1, 0, NULL);//唤醒等待队列
spin_unlock_irqrestore(&x->wait.lock, flags);
}
static void __wake_up_common(wait_queue_head_t *q, unsigned int mode, int nr_exclusive, int wake_flags, void *key)
{
wait_queue_t *curr, *next;
list_for_each_entry_safe(curr, next, &q->task_list, task_list) {
unsigned flags = curr->flags;
if (curr->func(curr, mode, wake_flags, key) &&
(flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
break;
}
}
int default_wake_function(wait_queue_t *curr, unsigned mode, int wake_flags,
void *key)
{
return try_to_wake_up(curr->private, mode, wake_flags);
}
阅读(4034) | 评论(0) | 转发(0) |