スピンロックのLinuxデバイスドライバ

コンセプト

スピンロックコードは、もはや休止、そのような割り込み処理ルーチンとして使用することはできません。適切に使用される場合、スピン・ロックは、一般セマフォの性能よりも高く提供することができます。

ミューテックスはスピンロック装置であり、それは2つのだけの値、ロック及びアンロックすることによるものである。一般に、単一ビット整数値として実装され、ロックが利用可能である場合、ロックに関連する特定のビットコードをテストしたい、ロックビットがセットされ、それがクリティカルセクション入力駄々をこねるし続けている、逆にロックが、他の誰かを取得するには、ロックループをチェックし、ロックが使用可能になるまで繰り返し、その後コードビジー状態の場合、このスピンロックスピンサイクルパーツであります;

スピンロックは、異なるアーキテクチャ上で実装が異なっているが、コアの概念は、任意の有用な作業を行うことができない忙しいサイクルを実行するためのプロセッサを待って、スピンロックがある場合、すべてのシステムが、同じよりも低くなっています。

スピンロックは元々のアカウントに同時実行の問題を取って設計されたマルチプロセッサシステム、上で使用するために、シングルプロセッサワークステーションは、SMPのように振る舞うプリエンプティブカーネルを実行している ;ので、つかむ、SMPシステム上で実行することを意図していない場合でも、彼らの駄々をこねるが、我々はまだ正しいロックを達成する必要があります。

スピンロックのコンテキスト原子と

スピンロックのルールに適している:任意のコードがスピンロックがアトミックである必要があります持っている、それは眠ることができない。いくつかのケースでは(実際には、それはまた、この時点での混乱にサービスを提供するほかに、何らかの理由でプロセッサを放棄することはできませんあなたは)プロセッサを放棄することはできません。

いつでも、限り、カーネルコードが禁止される関連するプロセッサにつかむためにスピンロックを、持っているとして;カーネルプリエンプションは、スピンロック処理コード自体を持っていても、単一のプロセッサ上で、あなたも同じようにプリエンプションを無効にする必要がありますレースを避けるために、

ロックを保持することは睡眠を避けるために、時には非常に困難である場合には、睡眠が多くの場所で発生する可能性があり、我々はスピンロックで実行されるコードを書くとき、あなたは各コールの機能に注意を払う必要があり、期待することはできません。

別の場合、ドライバが実行され、デバイスへのアクセスを制御するロックを獲得したとき、この時点で、デバイスは、割り込みを発生し、割り込み処理ルーチンが起動させる。中断処理例割り込み処理ルーチンでロックが合法である持っている;しかし、スピンロックで初期で取得したとき、ルーチンはロックコードプロセッサ上で実行している割り込み処理デバイスにアクセスするだけでなく、ロックを獲得する前に、チェン状態は、無停止でのコードは、ロックを解除するためにあらゆる機会を持っていないであろう時に、プロセッサはダウン永遠に回転します。あなたは、スピンロックを持っている場合、これを避けるために、我々は、ローカルCPUの割り込みを禁止する必要があります。

最後の重要なルールのスピンロックを使用:スピンロックが最短時間で持っている必要があります。長いスピンロック時間を所有し、他のプロセッサは、スピン - スピンロックの時間を解放するために長く待たなければなりません。このような問題を回避するために、心の中で可能な限り短くロックを持っている時間を保つ。これは、優先度の高いプロセスを待たなければならなかったことを意味する、現在のプロセッサのスケジューリングを防ぐことができます長いロックを持っています。

スピンロックの使用

スピンロックを使用することは<linux / spinlock.h>ヘッダを含める必要があり、ロックを有する実際のタイプ、および他の同様のデータ構造をspinlock_t、スピン・ロックが初期化されなければなりません。

コンパイルの静的宣言時には、以下の方法を初期化します。

1つ の#define DEFINE_SPINLOCK(X)

それとも、動的スピンロック初期化ランタイムに次のマクロを呼び出すことができます。

1つ の#define spin_lock_init(_lock)

重要なゾーンに入る前に、あなたがロックspin_lock相関関数を取得する必要があります。注:すべてのスピンロック待機がスピン状態のままになりますロックを取得する前に、本質的に非中断し、一度呼び出さspin_lockです。

1  静的 __always_inline 無効 spin_lock(spinlock_t * ロック2  
3  / * 禁止ソフト割り込み、ハードウェア割り込みが開かれた* / 
4  静的 __always_inline 無効 spin_lock_bh(spinlock_t * ロック5  
6  / * 、割り込み状態を保存せずに確保する必要性を地元の割り込みを禁止他のコードは、ローカル・プロセッサが割り込みを無効にしない/ * 
。7  静的 __always_inline 無効 spin_lock_irq(spinlock_t * ロック。8  
。9  / * 割り込みステータス、ローカル・プロセッサ割り込みを無効に保存* / 
10  の#define spin_lock_irqsaveを(ロック、フラグ)                

取得されたロックを解除するために、クリティカル領域を離れるときは、次の方法を使用することができます。

1  静的 __always_inline 空隙 spin_unlock(spinlock_t * ロック2  
3  静的 __always_inline 空隙 spin_unlock_bh(spinlock_t * ロック4  
5  静的 __always_inline 空隙 spin_unlock_irq(spinlock_t * ロック6  
7  静的 __always_inline 空隙 spin_unlock_irqrestore(spinlock_t * ロック、符号なしのロングフラグ)

カーネルは、非ブロッキングロック方法を提供します。

1  静的 __always_inlineのint型 spin_trylock(spinlock_t * ロック2  
3  静的 __always_inlineのint型 spin_trylock_bh(spinlock_t * ロック4  
5  静的 __always_inlineのint型 spin_trylock_irq(spinlock_t * ロック6  
7  の#define spin_trylock_irqsave(ロック、フラグ)
読み書きスピンロック

からの読み取り/書き込み、その作家は、スピンロックを取得するために待機される、カーネルはこのロックは、クリティカルセクションを入力すると同時に、読者の任意の数を可能にする、スピンロックの読み取り/書き込みフォームを提供していますが、筆者は、相互に排他的なアクセスでなければなりませんツイストロックは、両方の読み書きをヘッダファイルを含める必要がスピン・ロックを使用しては<linux / rwlock_types.h>とは<linux / rwlock.h>で定義rwlock_tタイプを使用します。

static宣言と初期化:

1つ の#define DEFINE_RWLOCK(X)

動的な宣言と初期化:

1つの#はrwlock_initを定義する(ロック

次のようにロックを取得します:

 

おすすめ

転載: www.cnblogs.com/wanpengcoder/p/11760722.html