This function inserts an entry, usually a packet, at the head of a doubly linked list so that access to the list is synchronized in a multiprocessor-safe way.
Header file: | Ndis.h |
Windows CE versions: | 2.0 and later |
PLIST_ENTRY NdisInterlockedInsertHeadList(
IN PLIST_ENTRY ListHead, IN PLIST_ENTRY ListEntry,
IN PNDIS_SPIN_LOCK SpinLock );
Returns a pointer to the entry that was at the head of the queue before the specified entry was inserted. If the queue was empty, it returns NULL.
Before calling this function, a driver must initialize the variable at ListHead with the NdisInitializeListHead function and the variable at SpinLock with the NdisAllocateSpinLock function. The driver must also provide resident storage for these variables and for its internal queue.
The caller-supplied spin lock prevents any other function from accessing the driver’s internal queue while this function is inserting the given entry, even when the driver is running on a multiprocessor machine.
This function raises IRQL to DISPATCH_LEVEL when it acquires the specified spin lock and restores the original IRQL before it returns control. Consequently, any driver function that calls this function cannot be pageable code.
Most NDIS drivers process packets in first-in, first-out ( FIFO ) order, so any driver that uses an interlocked queue tends to call the NdisInterlockedInsertTailList function far more frequently than this function. Such a driver usually calls this function only to requeue a packet for a retry operation.
To convert a returned value back to the address of the inserted entry, a driver can use the CONTAINING_RECORD macro.
A driver that calls this function runs at IRQL <= DISPATCH_LEVEL.
NdisAllocateSpinLock, NdisInitializeListHead, NdisInterlockedInsertTailList, NdisInterlockedRemoveHeadList