排他制御関連
Rev.2を表示中。最新版はこちら。
割り込み禁止
cli()で割り込み禁止状態にする。マルチプロセッサ環境においては意味がない。CONFIG_SMP定義の有無によって異なる。
CONFIG_SMP未定義時
cli命令実行するだけ
CONFIG_SMP定義時
定義がない。
2.4では全CPUで割り込みを禁止していた。
(RemoteCPUでは割り込みハンドラ実行を遅延させている)
そもそも、マルチプロセッサでは割り込み禁止だけでは
排他制御はできない。
(RemoteCPUでは割り込みハンドラ実行を遅延させている)
そもそも、マルチプロセッサでは割り込み禁止だけでは
排他制御はできない。
spinlockによるプロセッサ間の排他も必要。
<-- このためにspin_lock_irqsave()があり、
cli()は意味がなくなったため消された。
<-- このために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()も実行され、
暗黙でプリエンプションは不可とされる。