Linux Kernel(2.6)の実装に関するメモ書き

WaitQueue


Rev.14を表示中。最新版はこちら

Sleep,Blockするプロセスをつないでおくリスト。Sleep要因によってそれぞれWaitQueueがある。WaitQueueにつないだプロセスは、wake_upxxx()でWaitQueueを指定することで、RUNNING状態に戻る。WaitQueueは使わなくてもBlockは可能。


WaitQueueの構造
wait_queue_head_t
+-----------+
| lock | wait_queue_t
| task_list | ----> +---------+ ----> +---------+
+-----------+ | | | |
| func | | |
| | | |



[関連ルーチン]
init_waitqueue_head()
WaitQueue(wait_queue_head)を初期化する。

add_wait_queue()
指定WaitQueueにエントリを追加する。

add_wait_queue_exclusive()
指定WaitQueueに排他モード(*1)でエントリを追加する。エントリのflagsにはWQ_FLAG_EXCLUSIVEがセットされる。排他モードのエントリはWakeup時にWakeupする個数を指定できる。

(*1) 排他モードはWakeupするプロセス数を指定したい場合に使う。例えばセマフォでのブロック処理で使われている(__up(),__down())。セマフォを解放して、セマフォ待ちのプロセスをWakeupする際、全ての待ちプロセスをWakeupしても、セマフォはどれか1つのプロセスしか取れず、それ以外のプロセスは結局ブロックしてしまい無駄になってしまう。このため、__down()でブロックする際は排他モードでWaitQueueに積み、__up()でWakeupする際は、wake_up()でプロセスを1つだけWakeupさせている。

DECLARE_WAITQUEUE()
WaitQueueに積むエントリ(wait_queue_t)を初期化する。

DEFINE_WAIT()
WaitQueueに積むエントリ(wait_queue_t)を初期化する。
DECLARE_WAITQUEUE()との違いはWakeupすると、WaitQueueから自動的にエントリが削除される点。Wakeup時のハンドラにautoremove_wake_function()が設定されていて、ここでエントリ悪削除する。

wake_up()
指定WaitQueueの全Non ExclusiveプロセスとExclusiveプロセス1つ(*2)をWakeupする。
Wakeupしただけでは、WaitQueueから削除されないので注意(DEFINE_WAIT()でエントリを作った場合は除く)。

(*2) __wake_up_commonを見ると、Exclusiveプロセスを指定数Wakeupしたらループをbreakしているので全てのNon ExclusiveプロセスがWakeupされないように見える。しかし、WaitQueueに積む際、Non Exclusiveプロセスはキューの先頭から、Exclusiveプロセスはキューの末尾から積むようにしているので、Non Exclusiveプロセスはキューの前の方に集まっており全てのNon ExclusiveプロセスがWakeupされている。


wake_up_all()
指定WaitQueueの全プロセスをWakeupする。


[関連ページ]
プロセスのBlockとWakeup


最終更新 2006/06/25 21:45:53 - kztomita
(2006/06/24 19:12:58 作成)


リンク
最近更新したページ
検索