Condividi tramite


Multiprocessor-Safe

Il sistema operativo basato su Microsoft Windows NT è progettato per l'esecuzione uniformemente su piattaforme uniprocessor e multiprocessore simmetrico (SMP) e i driver in modalità kernel devono essere progettati in modo analogo.

In qualsiasi piattaforma multiprocessore windows esistono le condizioni seguenti:

  • Tutte le CPU sono identiche e tutti o nessuno dei processori deve avere coprocessori identici.

  • Tutte le CPU condividono la memoria e hanno accesso uniforme alla memoria.

  • In una piattaforma simmetrica ogni CPU può accedere alla memoria, eseguire un'interruzione e accedere ai registri di controllo I/O. (Al contrario, in un computer multiprocessore asimmetrico , una CPU accetta tutti gli interruzioni per un set di CPU subordinate.

Per eseguire in modo sicuro su una piattaforma SMP, un sistema operativo deve garantire che il codice eseguito su un processore non acceda contemporaneamente e modifica i dati che un altro responsabile accede e modifica. Ad esempio, se l'ISR di un driver di livello più basso gestisce un interruzione del dispositivo su un processore, deve avere accesso esclusivo ai registri dei dispositivi o ai dati critici, definiti dal driver, nel caso in cui il dispositivo interrompe contemporaneamente su un altro processore.

Inoltre, le operazioni di I/O dei driver serializzate in un computer uniprocessore possono essere sovrapposte in un computer SMP. Vale a dire, la routine di un driver che elabora le richieste di I/O in ingresso può essere eseguita su un processore mentre un'altra routine che comunica con il dispositivo viene eseguita simultaneamente su un altro processore. Se i driver in modalità kernel vengono eseguiti in un computer uniprocessor o multiprocessore simmetrico, devono sincronizzare l'accesso a tutti i dati definiti dal driver o alle risorse fornite dal sistema condivise tra routine driver e sincronizzare l'accesso al dispositivo fisico, se presente.

Il componente kernel Windows NT esporta un meccanismo di sincronizzazione, denominato blocco spin, che i driver possono usare per proteggere i dati condivisi (o i registri dei dispositivi) dall'accesso simultaneo da una o più routine che vengono eseguite simultaneamente in una piattaforma multiprocessore simmetrica. Il kernel applica due criteri relativi all'uso di blocchi di spin:

  • Una sola routine può contenere un determinato blocco di rotazione in qualsiasi momento. Prima di accedere ai dati condivisi, ogni routine che deve fare riferimento ai dati deve prima tentare di acquisire il blocco di rotazione dei dati. Per accedere agli stessi dati, un'altra routine deve acquisire il blocco di spin, ma il blocco di spin non può essere acquisito fino a quando il titolare corrente lo rilascia.

  • Il kernel assegna un valore IRQL a ogni blocco spin nel sistema. Una routine in modalità kernel può acquisire un determinato blocco spin solo quando la routine viene eseguita al irQL assegnato dal blocco spin.

Questi criteri impediscono una routine del driver che in genere viene eseguita in un irQL inferiore, ma attualmente contiene un blocco di rotazione da essere preceduto da una routine driver con priorità superiore che sta tentando di acquisire lo stesso blocco di rotazione. Pertanto, viene evitato un deadlock.

IrQL assegnato a un blocco di spin è in genere quello della routine IRQL più alta che può acquisire il blocco di rotazione.

Ad esempio, l'ISR di un driver di livello più basso condivide spesso un'area di stato con la routine DPC del driver. La routine DPC chiama una routine di sezione critica fornita dal driver per accedere all'area condivisa. Il blocco di rotazione che protegge l'area condivisa ha un IRQL uguale a DIRQL in corrispondenza del quale il dispositivo interrompe. Purché la routine di sezione critica contenga il blocco di rotazione e accede all'area condivisa in DIRQL, l'ISR non può essere eseguito in un computer uniprocessor o SMP.

  • L'ISR non può essere eseguito in un computer uniprocessor perché l'interruzione del dispositivo viene mascherata, come descritto in Always Preemptible e Always Interruptible.

  • In un computer SMP l'ISR non può acquisire il blocco di spin che protegge i dati condivisi mentre la routine di sezione critica contiene il blocco spin e accede ai dati condivisi in DIRQL.

Un set di thread in modalità kernel può sincronizzare l'accesso ai dati o alle risorse condivise aspettando uno degli oggetti dispatcher del kernel: un evento, un mutex, un semaforo, un timer o un altro thread. Tuttavia, la maggior parte dei driver non configura i propri thread perché hanno prestazioni migliori quando evitare commutatori di thread-contesto. Ogni volta che le routine e i driver in modalità kernel critici vengono eseguiti in IRQL = DISPATCH_LEVEL o in DIRQL, devono usare i blocchi di spin del kernel per sincronizzare l'accesso ai dati o alle risorse condivise.

Per altre informazioni, vedere Blocchi spin, Gestione delle priorità hardware e oggetti dispatcher kernel.