-impl. KeRemoveEntryDeviceQueue

-added irql asserts
-misc. small fixes and cleanups

svn path=/trunk/; revision=6475
This commit is contained in:
Gunnar Dalsnes 2003-10-31 00:14:09 +00:00
parent 286ec91295
commit b872ea2cad

View file

@ -17,55 +17,54 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
VOID
InsertBeforeEntryInList(PLIST_ENTRY Head, PLIST_ENTRY After, PLIST_ENTRY Entry)
{
InsertHeadList(After, Entry);
}
/* /*
* @implemented * @implemented
*/ */
BOOLEAN STDCALL BOOLEAN STDCALL
KeInsertByKeyDeviceQueue (PKDEVICE_QUEUE DeviceQueue, KeInsertByKeyDeviceQueue (
PKDEVICE_QUEUE_ENTRY DeviceQueueEntry, IN PKDEVICE_QUEUE DeviceQueue,
ULONG SortKey) IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry,
IN ULONG SortKey)
{ {
KIRQL oldlvl; PLIST_ENTRY current;
PLIST_ENTRY current; PKDEVICE_QUEUE_ENTRY entry;
PKDEVICE_QUEUE_ENTRY entry;
DPRINT("KeInsertByKeyDeviceQueue()\n"); DPRINT("KeInsertByKeyDeviceQueue()\n");
assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
DeviceQueueEntry->SortKey=SortKey; DeviceQueueEntry->SortKey=SortKey;
KeAcquireSpinLock(&DeviceQueue->Lock,&oldlvl); KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
if (!DeviceQueue->Busy) if (!DeviceQueue->Busy)
{ {
DeviceQueue->Busy=TRUE; DeviceQueue->Busy=TRUE;
KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl); KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
return(FALSE); return(FALSE);
} }
current=DeviceQueue->DeviceListHead.Flink; /*
while (current!=(&DeviceQueue->DeviceListHead)) Insert new entry after the last entry with SortKey less or equal to passed-in SortKey.
{ NOTE: walking list in reverse order.
entry = CONTAINING_RECORD(current,KDEVICE_QUEUE_ENTRY,DeviceListEntry); */
if (entry->SortKey < SortKey) current=DeviceQueue->DeviceListHead.Blink;
{ while (current!=(&DeviceQueue->DeviceListHead))
InsertBeforeEntryInList(&DeviceQueue->DeviceListHead, {
&DeviceQueueEntry->DeviceListEntry, entry = CONTAINING_RECORD(current,KDEVICE_QUEUE_ENTRY,DeviceListEntry);
current); if (entry->SortKey <= SortKey)
KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl); {
return(TRUE); /* insert new entry after current entry */
} InsertTailList(current, &DeviceQueueEntry->DeviceListEntry);
current = current->Flink; KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
} return(TRUE);
InsertTailList(&DeviceQueue->DeviceListHead,&DeviceQueueEntry->DeviceListEntry); }
current = current->Blink;
}
KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl); InsertHeadList(&DeviceQueue->DeviceListHead,&DeviceQueueEntry->DeviceListEntry);
return(TRUE);
KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
return(TRUE);
} }
/* /*
@ -74,36 +73,46 @@ KeInsertByKeyDeviceQueue (PKDEVICE_QUEUE DeviceQueue,
PKDEVICE_QUEUE_ENTRY PKDEVICE_QUEUE_ENTRY
STDCALL STDCALL
KeRemoveByKeyDeviceQueue ( KeRemoveByKeyDeviceQueue (
PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE DeviceQueue,
ULONG SortKey IN ULONG SortKey
) )
{ {
KIRQL oldlvl; PLIST_ENTRY current;
PLIST_ENTRY current; PKDEVICE_QUEUE_ENTRY entry;
PKDEVICE_QUEUE_ENTRY entry;
assert_irql(DISPATCH_LEVEL); assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
assert(DeviceQueue!=NULL); assert(DeviceQueue!=NULL);
assert(DeviceQueue->Busy); assert(DeviceQueue->Busy);
KeAcquireSpinLock(&DeviceQueue->Lock,&oldlvl); KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
current = DeviceQueue->DeviceListHead.Flink; /* an attempt to remove an entry from an empty (and busy) queue sets the queue to idle */
while (current != &DeviceQueue->DeviceListHead) if (IsListEmpty(&DeviceQueue->DeviceListHead))
{ {
entry = CONTAINING_RECORD(current,KDEVICE_QUEUE_ENTRY,DeviceListEntry); DeviceQueue->Busy = FALSE;
if (entry->SortKey < SortKey || KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
current->Flink == &DeviceQueue->DeviceListHead) return NULL;
{ }
RemoveEntryList(current);
KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl); /* find entry with SortKey greater than or equal to the passed-in SortKey */
return(entry); current = DeviceQueue->DeviceListHead.Flink;
} while (current != &DeviceQueue->DeviceListHead)
current = current->Flink; {
} entry = CONTAINING_RECORD(current,KDEVICE_QUEUE_ENTRY,DeviceListEntry);
DeviceQueue->Busy = FALSE; if (entry->SortKey >= SortKey)
KeReleaseSpinLock(&DeviceQueue->Lock, oldlvl); {
return(NULL); RemoveEntryList(current);
KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
return entry;
}
current = current->Flink;
}
/* if we didn't find a match, return the first entry */
current = RemoveHeadList(&DeviceQueue->DeviceListHead);
KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
return CONTAINING_RECORD(current,KDEVICE_QUEUE_ENTRY,DeviceListEntry);
} }
/* /*
@ -112,8 +121,7 @@ KeRemoveByKeyDeviceQueue (
PKDEVICE_QUEUE_ENTRY PKDEVICE_QUEUE_ENTRY
STDCALL STDCALL
KeRemoveDeviceQueue ( KeRemoveDeviceQueue (
PKDEVICE_QUEUE DeviceQueue IN PKDEVICE_QUEUE DeviceQueue)
)
/* /*
* FUNCTION: Removes an entry from a device queue * FUNCTION: Removes an entry from a device queue
* ARGUMENTS: * ARGUMENTS:
@ -121,29 +129,28 @@ KeRemoveDeviceQueue (
* RETURNS: The removed entry * RETURNS: The removed entry
*/ */
{ {
KIRQL oldlvl;
PLIST_ENTRY list_entry; PLIST_ENTRY list_entry;
PKDEVICE_QUEUE_ENTRY entry;
DPRINT("KeRemoveDeviceQueue(DeviceQueue %x)\n",DeviceQueue); DPRINT("KeRemoveDeviceQueue(DeviceQueue %x)\n",DeviceQueue);
assert_irql(DISPATCH_LEVEL); assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
assert(DeviceQueue!=NULL); assert(DeviceQueue!=NULL);
assert(DeviceQueue->Busy); assert(DeviceQueue->Busy);
KeAcquireSpinLock(&DeviceQueue->Lock,&oldlvl); KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
/* an attempt to remove an entry from an empty (and busy) queue sets the queue idle */
if (IsListEmpty(&DeviceQueue->DeviceListHead))
{
DeviceQueue->Busy = FALSE;
KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
return NULL;
}
list_entry = RemoveHeadList(&DeviceQueue->DeviceListHead); list_entry = RemoveHeadList(&DeviceQueue->DeviceListHead);
if (list_entry==(&DeviceQueue->DeviceListHead)) KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
{
DeviceQueue->Busy=FALSE;
KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
return(NULL);
}
KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl);
entry = CONTAINING_RECORD(list_entry,KDEVICE_QUEUE_ENTRY,DeviceListEntry); return CONTAINING_RECORD(list_entry,KDEVICE_QUEUE_ENTRY,DeviceListEntry);
return(entry);
} }
/* /*
@ -152,7 +159,7 @@ KeRemoveDeviceQueue (
VOID VOID
STDCALL STDCALL
KeInitializeDeviceQueue ( KeInitializeDeviceQueue (
PKDEVICE_QUEUE DeviceQueue IN PKDEVICE_QUEUE DeviceQueue
) )
/* /*
* FUNCTION: Intializes a device queue * FUNCTION: Intializes a device queue
@ -172,8 +179,8 @@ KeInitializeDeviceQueue (
BOOLEAN BOOLEAN
STDCALL STDCALL
KeInsertDeviceQueue ( KeInsertDeviceQueue (
PKDEVICE_QUEUE DeviceQueue, IN PKDEVICE_QUEUE DeviceQueue,
PKDEVICE_QUEUE_ENTRY DeviceQueueEntry IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry
) )
/* /*
* FUNCTION: Inserts an entry in a device queue * FUNCTION: Inserts an entry in a device queue
@ -184,33 +191,57 @@ KeInsertDeviceQueue (
* True otherwise * True otherwise
*/ */
{ {
KIRQL oldlvl; assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
KeAcquireSpinLock(&DeviceQueue->Lock,&oldlvl); KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
if (!DeviceQueue->Busy) if (!DeviceQueue->Busy)
{ {
DeviceQueue->Busy=TRUE; DeviceQueue->Busy=TRUE;
KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl); KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
return(FALSE); return(FALSE);
} }
InsertTailList(&DeviceQueue->DeviceListHead, DeviceQueueEntry->SortKey=0;
&DeviceQueueEntry->DeviceListEntry); InsertTailList(&DeviceQueue->DeviceListHead, &DeviceQueueEntry->DeviceListEntry);
DeviceQueueEntry->SortKey=0;
KeReleaseSpinLock(&DeviceQueue->Lock,oldlvl); KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
return(TRUE); return(TRUE);
} }
/* /*
* @unimplemented * @implemented
*/ */
BOOLEAN STDCALL BOOLEAN STDCALL
KeRemoveEntryDeviceQueue(PKDEVICE_QUEUE DeviceQueue, KeRemoveEntryDeviceQueue(
PKDEVICE_QUEUE_ENTRY DeviceQueueEntry) IN PKDEVICE_QUEUE DeviceQueue,
IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
{ {
UNIMPLEMENTED; PLIST_ENTRY current;
return(FALSE); KIRQL oldIrql;
PKDEVICE_QUEUE_ENTRY entry;
assert(KeGetCurrentIrql() <= DISPATCH_LEVEL);
KeAcquireSpinLock(&DeviceQueue->Lock, &oldIrql);
current = DeviceQueue->DeviceListHead.Flink;
while (current != &DeviceQueue->DeviceListHead)
{
entry = CONTAINING_RECORD(current, KDEVICE_QUEUE_ENTRY, DeviceListEntry);
if (DeviceQueueEntry == entry)
{
RemoveEntryList(current);
KeReleaseSpinLock(&DeviceQueue->Lock, oldIrql);
/* entry was in the queue (but not anymore) */
return TRUE;
}
current = current->Flink;
}
KeReleaseSpinLock(&DeviceQueue->Lock, oldIrql);
/* entry wasn't in the queue */
return FALSE;
} }