Condividi tramite


Sempre Preemptible e Always Interruptible

L'obiettivo della progettazione preemptible e interrotta del sistema operativo consiste nel ottimizzare le prestazioni del sistema. Qualsiasi thread può essere preceduto da un thread con una priorità maggiore e la routine del servizio di interruzione del driver può essere interrotta da una routine che viene eseguita a un livello di richiesta di interruzione superiore (IRQL).

Il componente kernel determina quando viene eseguita una sequenza di codice, in base a uno di questi criteri di priorità:

  • Schema di priorità di runtime definito dal kernel per i thread.

    Ogni thread nel sistema ha un attributo di priorità associato. In generale, la maggior parte dei thread ha attributi di priorità variabile : sono sempre preemptible e sono pianificati per eseguire round robin con tutti gli altri thread attualmente allo stesso livello di priorità. Alcuni thread hanno attributi di priorità in tempo reale : questi thread critici vengono eseguiti al completamento, a meno che non vengano preceduti da un thread con un attributo di priorità in tempo reale superiore. L'architettura di Microsoft Windows non fornisce un sistema intrinsecamente in tempo reale.

    Indipendentemente dall'attributo di priorità, qualsiasi thread nel sistema può essere preceduto quando si verificano interruzioni hardware e determinati tipi di interruzioni software.

  • Livello di richiesta di interruzione definito dal kernel (IRQL) a cui viene assegnato un particolare vettore di interruzione in una determinata piattaforma.

    Il kernel assegna priorità all'hardware e ai interruzioni software in modo che alcuni driver in modalità kernel, inclusi la maggior parte dei driver, venga eseguito con irQLs più elevati, rendendo così più elevato la priorità di pianificazione rispetto ad altri thread nel sistema. Il particolare IRQL in cui viene eseguito un pezzo di codice driver in modalità kernel è determinato dalla priorità hardware del dispositivo sottostante.

    Il codice in modalità kernel è sempre interrotto: un interruzione con un valore IRQL superiore può verificarsi in qualsiasi momento, causando così un altro pezzo di codice in modalità kernel con un irQL assegnato al sistema superiore da eseguire immediatamente su tale processore. Tuttavia, quando un pezzo di codice viene eseguito in un determinato IRQL, il kernel maschera tutti i vettori di interruzione con un valore IRQL minore o uguale al processore.

Il livello IRQL più basso viene chiamato PASSIVE_LEVEL. A questo livello non vengono mascherati vettori di interruzione. I thread vengono in genere eseguiti in IRQL=PASSIVE_LEVEL. I successivi livelli IRQL più elevati sono per gli interruzioni software. Questi livelli includono APC_LEVEL, DISPATCH_LEVEL o, per il debug del kernel, WAKE_LEVEL. Gli interruzioni dei dispositivi hanno valori IRQL ancora più elevati. Il kernel riserva i valori IRQL più alti per gli interruzioni critiche del sistema, ad esempio quelli dell'orologio di sistema o degli errori del bus.

Alcune routine di supporto del sistema vengono eseguite in IRQL=PASSIVE_LEVEL, perché vengono implementate come codice paginabile o dati a cui accede o perché alcuni componenti in modalità kernel configurano i propri thread.

Analogamente, alcune routine di driver standard vengono in genere eseguite in IRQL=PASSIVE_LEVEL. Tuttavia, diverse routine di driver standard vengono eseguite in IRQL=DISPATCH_LEVEL o, per un driver di livello più basso, al dispositivo IRQL (chiamato anche DIRQL). Per altre informazioni sugli IRQLs, vedere Gestione delle priorità hardware.

Ogni routine in un driver è interrotta. Ciò include qualsiasi routine in esecuzione a un irQL superiore rispetto a PASSIVE_LEVEL. Qualsiasi routine in esecuzione in un particolare IRQL mantiene il controllo del processore solo se non si verifica alcun interruzione per un irQL superiore durante l'esecuzione della routine.

A differenza dei driver in alcuni sistemi operativi personali meno recenti, l'ISR del driver Di Microsoft Windows non è mai una routine complessa e complessa che esegue la maggior parte dell'elaborazione I/O del driver. Ciò è dovuto al fatto che la routine del servizio di interruzione del driver (ISR) può essere interrotta da un'altra routine (ad esempio, dall'ISR di un altro driver) eseguita in un irQL superiore. Pertanto, l'ISR del driver non mantiene necessariamente il controllo di una CPU, senza interruzioni, dall'inizio del percorso di esecuzione alla fine.

Nei driver di Windows, un ISR salva in genere le informazioni sullo stato hardware, accoda una chiamata di procedura posticipata (DPC) e quindi termina rapidamente. Successivamente, il sistema dequeue il DPC del driver in modo che il driver possa completare le operazioni di I/O in un irQL inferiore (DISPATCH_LEVEL). Per prestazioni generali di sistema ottimali, tutte le routine eseguite con irQLs elevati devono rimettere rapidamente il controllo della CPU.

In Windows tutti i thread hanno un contesto di thread. Questo contesto è costituito da informazioni che identificano il processo proprietario del thread, oltre ad altre caratteristiche, ad esempio i diritti di accesso del thread.

In generale, solo un driver di livello più alto viene chiamato nel contesto del thread che richiede l'operazione di I/O corrente del driver. Un driver intermedio o di livello più basso non può mai presumere che sia in esecuzione nel contesto del thread che ha richiesto l'operazione di I/O corrente.

Di conseguenza, le routine del driver vengono eseguite in un contesto thread arbitrario, ovvero il contesto di qualsiasi thread sia corrente quando viene chiamata una routine di driver standard. Per motivi di prestazioni (per evitare commutatori di contesto), pochi driver configurano i propri thread.