セマフォの解放
Rev.2を表示中。最新版はこちら。
セマフォの解放は簡単です。up関数が呼ばれて、取得の時と同じようにspin_lock_irqsave関数で、スピンロックおよび割り込み禁止して、まずlist_empty関数でセマフォ待ちタスクがないか調べます。sem->wait_listが待ちリストの先頭リストで、sem->wait_list->next==sem->wait_listなら待ちリスト無し。ということで、sem->count++でセマフォを解放しておしまいです。(セマフォ取得時はsem->count--)待ちリストが空でない場合、__up関数を呼び出します。void up(struct semaphore *sem) { unsigned long flags; spin_lock_irqsave(&sem->lock, flags); if (likely(list_empty(&sem->wait_list))) sem->count++; else __up(sem); spin_unlock_irqrestore(&sem->lock, flags); }up関数では、待ちリストの先頭項目を取得し、その項目を待ちリストから削除し、waiter->up = 1そして、wake_up_process関数でそのタスクを、TASK_RUNNING状態としてウエイクアップします。セマフォ取得でセマフォ取得待ちタスクでは、schedule_timeout関数を挟んで、waiter->up=1となるまでループしていました。まさにwaiter->up = 1することで、セマフォ待ちしているタスクに実行権が移ると、セマフォが取得できて、めでたしめでたし。ということのようです。
static noinline void __sched __up(struct semaphore *sem) { struct semaphore_waiter *waiter = list_first_entry(&sem->wait_list, struct semaphore_waiter, list); list_del(&waiter->list); waiter->up = 1; wake_up_process(waiter->task); }
追伸
__up関数で、__schedマクロが付いています。これは以下のようになっていて、なにやらこの関数はセクションとして.sched.textにロケーションされるようで・・・。コメントみるとwchan出力では表示しない。ようなことが書いてありますが・・・。たぶんps等でwchanで表示する場合セマフォ待ちのタスクは本関数の表示をさせないよう、そのような関数をまとめて配置させたらなんか都合がいいのでしょうね。よく分かりませんが。* Attach to any functions which should be ignored in wchan output. */ #define __sched __attribute__((__section__(".sched.text")))