Funzione NdisAllocateSpinLock (ndis.h)

La funzione NdisAllocateSpinLock inizializza una variabile di tipo NDIS_SPIN_LOCK, usata per sincronizzare l'accesso alle risorse condivise tra le funzioni driver non ISR.

Sintassi

void NdisAllocateSpinLock(
  [out] PNDIS_SPIN_LOCK SpinLock
);

Parametri

[out] SpinLock

Puntatore a una variabile opaca che rappresenta un blocco di rotazione.

Valore restituito

nessuno

Osservazioni

Prima che un driver chiami NdisAcquireSpinLock, NdisDprAcquireSpinLock o una delle funzioni NdisInterlockedXxx , deve chiamare NdisAllocateSpinLock per inizializzare il blocco di selezione passato come parametro obbligatorio a queste funzioni NdisXxx . Il chiamante deve fornire spazio di archiviazione non in pagine per la variabile in SpinLock .

Dopo aver chiamato NdisAllocateSpinLock, il driver può chiamare NdisAcquireSpinLock per ottenere l'uso esclusivo delle risorse protette dal blocco spin. Al termine dell'accesso alle risorse, il driver chiama NdisReleaseSpinLock in modo che altre funzioni driver possano accedere alle risorse protette da tale blocco spin.

Come regola generale, per migliorare le prestazioni, un driver deve usare blocchi diversi per proteggere sezioni critiche diverse. Di conseguenza, un driver potrebbe inizializzare più di un blocco spin con NdisAllocateSpinLock.

Ogni blocco di selezione allocato da un driver protegge un set discreto di risorse condivise dall'accesso simultaneo da funzioni driver eseguite in IRQL <= DISPATCH_LEVEL. Ad esempio, un driver che gestisce una coda interna di pacchetti potrebbe inizializzare un blocco spin per proteggere la coda e un altro per proteggere un set di variabili di stato che diverse funzioni driver, non incluso MiniportInterrupt o Funzione MiniportDisableInterruptEx , accesso mentre il driver elabora i pacchetti.

NdisAcquireSpinLock genera irQL per DISPATCH_LEVEL e archivia il precedente IRQL nel blocco spin. Il rilascio del blocco spin imposta IRQL sul valore archiviato nel blocco spin. Poiché NDIS a volte immette i driver in PASSIVE_LEVEL, possono verificarsi problemi con il codice seguente:

NdisAcquireSpinLock(A);
NdisAcquireSpinLock(B);
NdisReleaseSpinLock(A);
NdisReleaseSpinLock(B);

Un driver non deve accedere ai blocchi di selezione in questa sequenza per i motivi seguenti:

  • Tra NdisReleaseSpinLock(A) e NdisReleaseSpinLock(B) il codice è in esecuzione in PASSIVE_LEVEL invece di DISPATCH_LEVEL ed è soggetto a un'interruzione inappropriata.
  • Dopo NdisReleaseSpinLock(B) il codice viene eseguito in DISPATCH_LEVEL che potrebbe causare l'errore del chiamante in un momento molto successivo con un errore di arresto IRQL_NOT_LESS_OR_EQUAL.
Un driver non deve mai usare due blocchi di rotazione per proteggere lo stesso set di risorse (sub)set di risorse perché le acquisizioni di blocchi spin annidati causano così frequentemente deadlock. Anche se un driver può essere progettato per evitare deadlock, le acquisizioni di blocco spin annidato hanno un effetto negativo sulle prestazioni del driver e sulla velocità effettiva di I/O.

Un driver miniport non può usare un blocco spin per proteggere le risorse condivise dalle funzioni non ISR con miniportInterrupt o Funzione MiniportDisableInterruptEx . Per accedere alle risorse condivise con una funzione MiniportInterrupt o MiniportDisableInterruptEx , un driver miniport deve chiamare NdisMSynchronizeWithInterruptEx per avere il relativoLa funzione MiniportSynchronizeInterrupt accede a tali risorse in DIRQL.

Quando un driver non richiede più la protezione delle risorse, ad esempio quando viene rimossa una scheda di interfaccia di rete e il driver rilascia le risorse allocate per tale scheda di interfaccia di rete, il driver chiama NdisFreeSpinLock.

Liberare un blocco di rotazione e rilasciare un blocco di rotazione è potenzialmente confuso. NdisFreeSpinLock cancella la memoria in SpinLock in modo che non rappresenti più un blocco di rotazione. Il rilascio di un blocco spin acquisito con NdisReleaseSpinLock consente semplicemente a un altro thread di esecuzione di acquisire tale blocco spin.

Per altre informazioni sull'acquisizione e il rilascio di blocchi di selezione NDIS, vedere Sincronizzazione e notifica nei driver di rete.

I chiamanti di NdisAllocateSpinLock possono essere eseguiti in qualsiasi IRQL. In genere un chiamante è in esecuzione in IRQL = PASSIVE_LEVEL durante l'inizializzazione.

Requisiti

Requisito Valore
Client minimo supportato Supportato per i driver NDIS 6.0 e NDIS 5.1 (vedere NdisAllocateSpinLock (NDIS 5.1)) in Windows Vista. Supportato per i driver NDIS 5.1 (vedere NdisAllocateSpinLock (NDIS 5.1)) in Windows XP.
Piattaforma di destinazione Universale
Intestazione ndis.h (include Ndis.h)
Libreria Ndis.lib
IRQL Qualsiasi livello (vedere la sezione Osservazioni)
Regole di conformità DDI SpinLockDpr(ndis), SpinLockDprRelease(ndis), SpinlockRelease(ndis)

Vedi anche

DriverEntry dei driver del protocollo NDIS

MiniportDisableInterruptEx

MiniportHaltEx

MiniportInitializeEx

MiniportInterrupt

NdisAcquireSpinLock

NdisDprAcquireSpinLock

NdisDprReleaseSpinLock

NdisFreeSpinLock

NdisInterlockedAddUlong

NdisInterlockedInsertHeadList NdisInterlockedInsertTailList NdisInterlockedRemoveHeadList NdisMSynchronizeWithInterruptEx

NdisReleaseSpinLock

NetTimerCallback