2016-10-30 4 views
3

Ich bin auf der Suche Scheduler-Code in Linux:Wann ist 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; 

Wie ich verstehe, wenn die prev Aufgabe uninterruptable ist, wird dieser Code die Aufgabe deaktivieren (und von Runqueue entfernen) versehen

preempt_count() & PREEMPT_ACTIVE == 0 

Kann jemand erklären mir, was ist preempt_count in thread_info für und wann wird diese Bedingung erfüllt oder nicht?

+0

preempt_counts obere Bits werden für Dinge wie IRQ-Zählungen verwendet, eines der Bits wird verwendet, um zu signalisieren, ob PREEMPT aktiv ist, was die Leitung prüft. –

+0

Aber ich dachte, schedule() konnte nicht im IRQ-Handler aufgerufen werden, da der Zeitplan schlafen kann. (Du bist nur durch Interrupt vorweggenommen? Sonst würdest du das richtig terminieren?) –

Antwort

0

preempt_count ist der von preempt_disable() und preempt_enable() verwendete Zähler, der ihre verschachtelte Verwendung ermöglicht. Bits höherer Ordnung von preempt_count werden für Hardirq- und Softirq-Zähler, ein NMI-Bit und ein PREEMPT_ACTIVE-Bit verwendet. Diese sind in include/linux/preempt_mask.h definiert. In x86-Architekturen wird auch ein PREEMPT_NEED_RESCHED-Bit in preempt_count verwendet, um die Entscheidung zum Umplanen zu optimieren.

Nun bin ich nicht klar über die genaue Notwendigkeit für die PREEMPT_ACTIVE Bit in preempt_count. In der Kernel-Version 3.17, die ich bearbeitet habe, wird PREEMPT_ACTIVE in preempt_count genau vor dem Aufruf __schedule() gesetzt und sofort nach dem Aufruf zurückgesetzt, in allen Fällen, außer wenn es von schedule() aufgerufen wird. Dies würde bedeuten, innerhalb __schedule(), PREEMPT_ACTIVE wird in preempt_count gesetzt, wenn __schedule() wegen Kernel-Vorkauf aufgerufen wurde, d. H. Nicht absichtlich für einige andere OS-Funktionalität, die schedule() verwenden würde. Was würde eine solche "andere Betriebssystemfunktionalität" sein, abhängig davon, ob Sie den Kernel mit CONFIG_PREEMPT, CONFIG_PREEMPT_VOLUNTARY oder CONFIG_PREEMPT_NONE erstellen, aber es enthält explizite Blockierung auf einem Mutex.