- work_queue 是一個 linking list,由一個 thread 負責,在 "適當時機" 把 queue 中的 work 取出來一一處理完畢。
- work 是一組資料結構,其實重要的地方是 call back function。
- work_queue 的"處理 thread" 實際上就是 把 work_queue 中的 work 一一取出,執行 work 裡面的 callback function。
宣告 work_queue
struct workqueue_struct *suspend_work_queue;
然後 create work queue: suspend_work_queue = create_singlethread_workqueue("suspend");
要放到 work_queue 的資料 "work",linux 有提供一個MACRO,方便宣告
static DECLARE_WORK(suspend_work, suspend);
suspend_work 就是新宣告的 work 資料, suspend 就是這個work 的callback function。static void suspend(struct work_struct *work)
{
int ret;
int entry_event_num;
if (has_wake_lock(WAKE_LOCK_SUSPEND)) {
if (debug_mask & DEBUG_SUSPEND)
pr_info("suspend: abort suspend\n");
return;
,,,,,
宣告完後,在需要的時候,把 work 放到 work_queue 中,,,
queue_work(suspend_work_queue, &suspend_work);
這樣就 OK 了..
work_queue 既然是 queue,所以可以放進很多 work。
以 kernel/power 為例,裡面共 create 了兩個 workqueue: suspend_work_queue,pm_wq。
suspend_work_queue 只有 kernel/power 自己使用,pm_wq 則是 public symbol, kernel 所有的 module 都可以用 (都可以放東西進 pm_wq workqueue裡)。
suspend_work_queue 在 kernel/power 中,被放進去的 work 有:
- suspend_work
- early_suspend_work
- late_resume_work..
為了方便 kernel module 使用 workqueue, kernel 提供一個 global 的 workqueue,使用這個 workqueue,就不用自己 create_workqueue..
這個 workqueue 就叫做 "公共workqueue"。
使用這個公共 workqueue,就不必用 queue_work( ),因為 work_queue 的名稱已經是 kernel 決定了。
在 kernel/workqueue.c 可以看到:
int schedule_work(struct work_struct *work)
{
return queue_work(keventd_wq, work);
}
EXPORT_SYMBOL(schedule_work);
用 schedule_work( ) 就是對公共 workqueue keventd_wq 作 queue_work( )。keventd_wq 也是在 kernel/workqueue.c 產生:
void __init init_workqueue()
{
....
keventd_wq = create_workqueue("events");
....
--- 所以這個公共的workqueue 的名子叫 "events"...
ref: http://www.ibm.com/developerworks/linux/library/l-tasklets/index.html
沒有留言:
張貼留言