Nota
L'accesso a questa pagina richiede l'autorizzazione. Puoi provare ad accedere o a cambiare directory.
L'accesso a questa pagina richiede l'autorizzazione. Puoi provare a cambiare directory.
I blocchi di rotazione in coda sono una variante di spin lock che funzionano bene per i blocchi fortemente contesi. I blocchi di rotazione tradizionali e unqueued sono una scelta migliore per i blocchi di durata leggeri o più brevi.
I vantaggi dell'uso di un blocco spin in coda includono:
Contesa del processore ridotta: i blocchi di selezione tradizionali possono causare conflitti significativi del processore quando più thread tentano di acquisire il blocco contemporaneamente, in quanto controllano lo stato del blocco in modo continuo (o "spin"). Ciò può ridurre le prestazioni del sistema, soprattutto nei sistemi multiprocessore. I blocchi di selezione in coda attenuano questo problema organizzando i thread in una coda. Quando un thread acquisisce un blocco, solo il successivo in linea sta ruotando attivamente, in attesa di acquisire il blocco. Ciò riduce i cicli della CPU sprecate durante la rotazione, soprattutto quando il blocco viene mantenuto per durate più lunghe.
Equità ed evitamento dell'affamamento: uno dei problemi con i blocchi di rotazione di base è la mancanza di equità; un thread può essere affamato e non acquisirà mai il blocco se altri thread lo acquisiscono e lo rilasciano continuamente. I blocchi di selezione in coda consentono di risolvere questo problema assicurandosi che i thread acquisiscano il blocco nell'ordine in cui hanno tentato di eseguire. Questa gestione sequenziale impedisce la fame e garantisce che tutti i thread vengano gestiti nel tempo.
Scalabilità: man mano che il numero di processori o core aumenta in un sistema, l'efficienza dei meccanismi di sincronizzazione diventa fondamentale per le prestazioni. I blocchi di rotazione in coda sono più scalabili rispetto ai blocchi di rotazione tradizionali perché riducono il sovraccarico sui processori riducendo al minimo la rotazione attiva tra tutti i core. Ciò è particolarmente importante nei sistemi multi-core ad alte prestazioni, in cui l'efficienza dei driver può influire direttamente sulle prestazioni complessive del sistema.
Uso efficiente delle risorse di sistema: riducendo i blocchi di rotazione del processore non necessari, i blocchi spin in coda consentono al sistema di usare le risorse in modo più efficiente. Ciò non solo migliora le prestazioni del driver di dispositivo, ma ha anche un impatto positivo sulla velocità di risposta complessiva e sul consumo di energia del sistema, che è particolarmente utile negli ambienti sensibili all'alimentazione.
Semplicità e affidabilità: nonostante i loro vantaggi nella riduzione della contesa e nel miglioramento dell'equità, i blocchi spin accodati astraggono la complessità dallo sviluppatore. Forniscono un meccanismo semplice e affidabile per proteggere le risorse condivise senza che lo sviluppatore deve implementare una logica di blocco complessa. Questa semplicità riduce la probabilità di bug correlati alla gestione non corretta dei blocchi, migliorando così l'affidabilità del driver.
Di seguito è riportato un frammento di codice semplificato che illustra le operazioni descritte con un spin lock in coda di un driver di Windows in modalità kernel. Questo esempio illustra come dichiarare e inizializzare un blocco spin usando KeInitializeSpinLock, quindi acquisire e rilasciare il blocco usando rispettivamente KeAcquireInStackQueuedSpinLock e KeReleaseInStackQueuedSpinLock.
KSPIN_LOCK SpinLock;
KLOCK_QUEUE_HANDLE LockHandle;
// Initialize the spin lock
KeInitializeSpinLock(&SpinLock);
// Assume this function is called in some kind of context where
// the below operations make sense, e.g., in a device I/O path
// Acquire the queued spin lock
KeAcquireInStackQueuedSpinLock(&SpinLock, &LockHandle);
// At this point, the current thread holds the spin lock.
// Perform thread-safe operations here.
// ...
// Release the queued spin lock
KeReleaseInStackQueuedSpinLock(&LockHandle);
Il driver alloca una struttura KLOCK_QUEUE_HANDLE che viene passata mediante un puntatore a KeAcquireInStackQueuedSpinLock. Il driver passa la stessa struttura tramite puntatore a KeReleaseInStackQueuedSpinLock quando rilascia lo spin lock.
I driver dovrebbero normalmente allocare la struttura nello stack ogni volta che acquisiscono il lock. Un driver non deve allocare la struttura come parte del contesto di dispositivo e quindi condividere la stessa struttura da più thread.
I driver non devono combinare le chiamate alle routine di blocco di selezione in coda e le normali routine SpinLockKe Xxx nello stesso blocco di selezione.
Se il driver è già all'IRQL = DISPATCH_LEVEL, può chiamare invece KeAcquireInStackQueuedSpinLockAtDpcLevel e KeReleaseInStackQueuedSpinLockFromDpcLevel.