排他制御関連
Rev.1を表示中。最新版はこちら。
cli() - 割り込み禁止 CONFIG_SMP未定義時 cli命令実行するだけ CONFIG_SMP定義時 定義がない。 2.4では全CPUで割り込みを禁止していた。 (RemoteCPUでは割り込みハンドラ実行を遅延させている) そもそも、マルチプロセッサでは割り込み禁止だけでは 排他制御はできない。 spinlockによるプロセッサ間の排他も必要。 <-- このためにspin_lock_irqsave()があり、 cli()は意味がなくなったため消された。 プロセッサ間の排他制御 spin_lock() SpinLock取得 取得できるまでSpin spin_lock_irqsave() LocalCPUについてcliで割り込み禁止にして、 SpinLock取得 割り込みハンドラからもlockを取ろうとする場合は、 DeadLock防止のため、こちらを使用する。 LocalCPUについて割り込み禁止しておかないと 通常ContextでSpinLock取得した後、 割り込みが発生して同じSpinLockを取ろうとした時、 DeadLockする。 他のCPUの割り込みは禁止にする必要はない。 セマフォ lock_kernel() カーネルセマフォ(kernel_sem)を取得。 down()によりセマフォが取れなければ TASK_UNINTERRUPTIBLE状態でSleepする。 プリエンプションの抑止 preempt_disable() current_thread_info()->preempt_countをインクリメントして プリエンプションを抑止 プリエンプト処理は例外/割り込みからカーネルモードに もどる時(entry.S::resume_kernel)にTIF_NEED_RESCHEDが立っていたら プロセスを切り替えることでおこなっているが、 preempt_countが0でなければプロセス切り替えが 発生しないようにしている。 spin_lockxxx()をするとpreempt_disable()も実行され、 暗黙でプリエンプションは不可とされる。