PLIST_ENTRY
NdisInterlockedRemoveHeadList(
IN PLIST_ENTRY ListHead,
IN PNDIS_SPIN_LOCK SpinLock
);
NdisInterlockedRemoveHeadList removes an entry, usually a packet, from the head of a doubly linked list so that access to the list is synchronized in a multiprocessor-safe way.
NdisInterlockedRemoveHeadList returns a pointer to the dequeued entry. If the list was empty, it returns NULL.
Before calling any NdisInterlocked..List function, a driver must initialize the variable at ListHead with NdisInitializeListHead and the variable at SpinLock with NdisAllocateSpinLock. The driver also must provide resident storage for these variables and for its internal queue.
Before calling NdisInterlockedRemoveHeadList, entries are queued with one or more calls to the NdisInterlockedInsert..List functions.
The caller-supplied spin lock prevents any other function from accessing the driver’s internal queue while NdisInterlockedRemoveHeadList is removing an entry, even when the driver is running on a multiprocessor machine.
NdisInterlockedRemoveHeadList raises IRQL to DISPATCH_LEVEL when it acquires the given spin lock and restores the original IRQL before it returns control. Consequently, any driver function that calls NdisInterlockedRemoveHeadList cannot be pageable code.
To convert a returned value back to the address of the inserted entry, a driver can use the CONTAINING_RECORD macro (see the Kernel-Mode Driver Reference).
Callers of NdisInterlockedRemoveHeadList run at IRQL <= DISPATCH_LEVEL.
NdisAllocateSpinLock, NdisInitializeListHead, NdisInterlockedInsertHeadList, NdisInterlockedInsertTailList