1

私はかなり長い間これを読んできましたが、私には意味がありません..おそらく、私はこれらすべてに不慣れで、カーネルの概念をほとんど理解していないためです。

これは私が思いついたものです(エラーやNULL処理はありません。質問のためだけです):

カーネル スピンロックは、プリエンティブなカーネル スレッド内で実行されます。

void spinlock_acquire(spinlock_t *spinlock)
{
  tryagain:
    while(spinlock->plock != UNLOCKED) ;
    context_switch_block;
    if(spinlock->plock != UNLOCKED) {
        context_switch_unblock;
        goto tryagain;
    }
    spinlock_lock(spinlock, current_thread);
    context_switch_unblock;
}
4

2 に答える 2

8

Linux がプリエンプティブ カーネルになる前は、UP のスピンロックは基本的にノーオペレーションでした。カーネルがプリエンプティブになると、への呼び出しpreempt_disable()がスピンロックに追加されました。

したがって、多かれ少なかれ次のようになります。

  • 競合するCPUから保護したい場合は、ある種のスピンロックを使用してください。
  • 競合する softirq、tasklet、... use から保護したい場合はspin_lock_bh、softirq、tasklet などを無効にします (bhは歴史的な名前で、「下半分」に由来します)。
  • ハードウェア割り込みを無効にする、競合するハードウェア割り込み使用から保護したいspin_lock_irq*
  • すべてのスピンロックはプリエンプションから保護します。
  • UP カーネルでは、スピンロックは実際のスピンロックを取得しません (競合する CPU がなく、プリエンプトされることはなく、hardirq、softirq などを処理するためのスピンロックのバリエーションがあるため)。
  • SMP カーネルを搭載した UP マシンでは、スピンロックが nop に変わることがあります。
  • プリエンプションが無効になっている UP カーネルでも、スピンロックが有効になっている場合は、スピンロックのデバッグ用のコードが含まれている可能性があります。
于 2012-07-22T20:07:10.367 に答える
2

非 SMP ではスピンロックは不要です。スピンロックが無効になっていると割り込みが発生するため、他のユーザーがその時点でロックを取得することはできません。スレッド A が割り込みを無効にすると、スレッド B が同じロックを取得しようとすることはできません。これは、A が B を優先して CPU を失う原因となるものは何もないためです。そのため、非 SMP で行われるすべてのスピンロックは、まあ、何もありません(割り込みを無効にするように依頼した場合を除く)。

シャチャー

于 2012-07-22T19:59:39.077 に答える