您的位置:首页 > 其它

USB的内核线程 与 完成量之间的关系 赏析

2016-03-22 22:01 309 查看

先看完成量

usb重要的内核线程

睡眠与唤醒

/**
看,完成量是由 等待队列 + 原子变量 来实现的。
那么,问题是  :
他们是怎么样来实现完成量的呢?

他的初始化函数会将done 设置为0
再complete()加1,wait_for_completion(以及他衍生出来的函数)减 1

再初始化函数中会初始化等待队列,
这里简单的说一下,具体的请往下看。有实验验证。
*/
struct completion {
unsigned int done;
wait_queue_head_t wait;
};

/**
这个函数 不会 timeout,哈哈。不像wait_for_completion_timeout()函数。
他们两个再内核中都会调用 schedule_timeout(timeout);只是传入的参数不同罢了。

那么wait_for_completion()传入的就是这个第二个参数 MAX_SCHEDULE_TIMEOUT。
而wait_for_completion_timeout()需要你传入一个时间,具体的欣赏再下面。

看他第三个参数,TASK_UNINTERRUPTIBLE,
这两个函数底层都会调用__set_current_state(state)函数,
都会将进程状态设置为 TASK_UNINTERRUPTIBLE。
*/
void __sched wait_for_completion(struct completion *x)
{
wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE);
}

static long __sched wait_for_common(struct completion *x, long timeout, int state)
{
might_sleep();
/**
这里有一个疑问。
再自旋锁保护的临界区 不能 调用有可能会睡眠的函数的。
但是 do_wait_for_common() 这个函数 最终可能会调用到 schedule();
这个又怎么解释?
*/
spin_lock_irq(&x->wait.lock);
/**
真正干活的是这个函数
*/
timeout = do_wait_for_common(x, timeout, state);
spin_unlock_irq(&x->wait.lock);
return timeout;
}




下面这幅图是我改动了内核源码打印出来的log

看内核线程



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: