1

私はいくつかのコードを読んでいて、関数 foo で見ました:

// x is a global variable shared by all functions
spin_lock(&x);
if(some condition)
    function();
spin_unlock(&x);

関数内();

// do stuff
spin_lock_irqsave(&x, vals);
....

「何らかの条件」が真の場合、デッドロックは発生しませんか? あまりにも明白に思えるので、何かが足りないのではないかと思いましたか?

ありがとう

編集:コードはLinuxの一部ではありません。オンラインで見つけたランダムなコードです

4

3 に答える 3

1

このコードはデッドロックします(再帰的なロックがなく、これがLinuxカーネルコードであると想定しています)。通常、irqバージョンのspin_lockは、コードが割り込みによってプリエンプションされないように保護する場合に使用されます。

valsの理由は、現在の割り込み状態を保存し、irqrestoreを呼び出すときにそれを復元するためです。これは、複数のスピンロックを取得したり、割り込みが無効になっているブロック内にいる場合に、割り込みを途中でオンにすることを回避するためです。

于 2012-10-07T06:34:26.273 に答える
1

スピンロックは再帰的ではなく、高性能ロックを目的としているため、おそらく再帰的ではありません。

したがって、条件が真の場合、投稿されたコードはデッドロックします。

于 2012-10-07T06:40:30.557 に答える
0

spin_lock()それはどのようにそしてどのように実行されたかに依存するでしょうspin_lock_irqsave()

たとえば、ロックが同じCPUによってすでにロックされているかどうかを判断し、ロックされている場合はカウンターをインクリメントすることができます。次に(ロックが解除されたときに)カウンタをデクリメントし、カウンタがゼロになった場合にのみロックを解除します。そうすれば、同じCPUがロックを複数回取得でき、デッドロックが発生することはありません。

spin_lock_irqsave()また、IRQを無効にするだけで、実際にはロックを取得しないもの(たとえば、spin_lock()事前に呼び出されたと想定/予期するもの)になる可能性もあります。この場合、ロック&xは、IRQが無効にされた/無効にされたという事実を保存/追跡するのに便利な場所である可能性があります(spin_unlock()フラグをチェックし、無効になっている場合はIRQを再度有効にします)。

spin_lock_irqsave()ただし、 2番目のパラメーター()が必要な理由は考えられませんvals

もう1つの可能性は、これらの関数の名前が誤解を招きやすく、実際に行っていることとはまったく関係がないことです。例えば; spin_lock()関数はピザを注文し、関数spin_lock_irqsave()はサッカーの結果を表示する場合があります。

基本的に、これらの関数に関する情報は名前以外にないため、それらが何をするか(またはデッドロックがあるかどうか)を判断することは不可能です。

于 2012-10-07T06:26:32.773 に答える