2016-10-30 4 views
3

私はLinuxのスケジューラのコードを探しています:preempt_count()とPREEMPT_ACTIVE == 0はいつですか?

if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) { 
    if (unlikely(signal_pending_state(prev->state, prev))) { 
     prev->state = TASK_RUNNING; 
    } else { 
     deactivate_task(rq, prev, DEQUEUE_SLEEP); 
     prev->on_rq = 0; 

私は理解しているように、prevタスクが無停電であれば、このコードは、タスクを無効に(と実行キューから削除)します

preempt_count() & PREEMPT_ACTIVE == 0 

をすることができ提供誰かがpreempt_countthread_infoについて何を説明していますか?この条件が満たされるかどうかはいつですか?

+0

preempt_counts上位ビットはIRQカウントのようなものに使用され、ビットの1つは、PREEMPTがアクティブであるかどうかを示すために使用されます。 –

+0

しかし、スケジュールがスリープできるので、schedule()をIRQハンドラで呼び出すことができないと考えました。 (あなたは割り込み権利によってのみ奪取されますか?そうでなければ、あなたは予定外になるでしょうか?) –

答えて

0

preempt_countは、ネストされた使用を可能にするpreempt_disable()およびpreempt_enable()によって使用されるカウンタです。 preempt_countの上位ビットは、hardirqおよびsoftirqカウンタ、NMIビット、およびPREEMPT_ACTIVEビットに使用されます。これらはinclude/linux/preempt_mask.hで定義されています。 x86アーキテクチャでは、PREEMPT_NEED_RESCHEDビットもpreempt_countで使用され、再スケジュールの決定を最適化します。

ここで、正確にはPREEMPT_ACTIVEビットがのであることがわかりません。私が取り組んでいるカーネルバージョン3.17では、schedule()から呼び出されたときを除いて、が__schedule()を呼び出す前に正確にpreempt_countに設定され、呼び出し直後にリセットされます。これは、カーネルのプリエンプションのために__schedule()が呼び出されたとき、つまりschedule()を使用する他のOSの機能には意図的ではないので、__schedule()の内部にPREEMPT_ACTIVEが設定されていることを意味します。このような「その他のOSの機能」は、CONFIG_PREEMPTCONFIG_PREEMPT_VOLUNTARY、またはCONFIG_PREEMPT_NONEというカーネルをビルドするかどうかによって異なりますが、ミューテックスに明示的なブロッキングが含まれています。

関連する問題