spin lock による排他制御 †
spin lock の種類 †
どのコンテキストでも使える spin_lock_irqsave() と spin_unlock_irqrestore() †
数多く有る spin lock のうちどのコンテキストでも使える spin_lock_irqsave(), spin_unlock_irqrestore() を覚えて使うのが良いでしょう。spin_lock_irqsave() spin_unlock_irqrestore() は状況によってはしなくても良い割り込み許可フラグの保存・復帰を無条件にします。無駄な処理かもしれません。それでも、実行時間の無駄よりは、spin_lock_irqsave(), spin_unlock_irqrestore() を呼び出した元のコンテキストが何か留意しながらコードを書くより安全な方法を推奨します。
spin_lock_irqsave() †
- ローカル CPU 割り込フラグ保存
- プリエンプション (preemption) 禁止
- ローカル CPU 割り込み禁止
- ロック変数を操作・確認するループを実行する
自分のコンテキストがロックを得た状態になるまでループを続ける。
spin_unlock_restore() †
- ロック変数を操作して自分のコンテキストがロックを得ていない状態にする
- プリエンプション (preemption) 許可
- ローカル CPU 割り込フラグ復帰
spin_lock_irqsave() と spin_unlock_irqrestore() の注意点 †
spin_lock_irqsave(), spin_unlock_irqrestore() の注意点を列挙します。
- 割り込み許可フラグを保存する変数 flags の渡し方に注意
- 長時間 lock 状態にしない
- spin lock の中からコンテキスト・スイッチが強制的に発生する関数は呼べない