- KeRundownThread:

- Optimize to reduce contention
 - Add bugcheck instead of ASSERT
 - Add debug message to simplify finding errors like Bug 821 (type/size show 0xCC, which means the mutant has been already freed).

svn path=/trunk/; revision=18183
This commit is contained in:
Alex Ionescu 2005-10-01 07:37:13 +00:00
parent 403e26da1b
commit 7cd4df132d

View file

@ -456,22 +456,40 @@ KeRundownThread(VOID)
{ {
KIRQL OldIrql; KIRQL OldIrql;
PKTHREAD Thread = KeGetCurrentThread(); PKTHREAD Thread = KeGetCurrentThread();
PLIST_ENTRY CurrentEntry; PLIST_ENTRY NextEntry, ListHead;
PKMUTANT Mutant; PKMUTANT Mutant;
DPRINT("KeRundownThread: %x\n", Thread); DPRINT("KeRundownThread: %x\n", Thread);
/* Optimized path if nothing is on the list at the moment */
if (IsListEmpty(&Thread->MutantListHead)) return;
/* Lock the Dispatcher Database */ /* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock(); OldIrql = KeAcquireDispatcherDatabaseLock();
while (!IsListEmpty(&Thread->MutantListHead)) { /* Get the List Pointers */
ListHead = &Thread->MutantListHead;
NextEntry = ListHead->Flink;
while (NextEntry != ListHead)
{
/* Get the Mutant */ /* Get the Mutant */
CurrentEntry = RemoveHeadList(&Thread->MutantListHead); Mutant = CONTAINING_RECORD(NextEntry, KMUTANT, MutantListEntry);
Mutant = CONTAINING_RECORD(CurrentEntry, KMUTANT, MutantListEntry); DPRINT1("Mutant: %p. Type, Size %x %x\n", Mutant, Mutant->Header.Type, Mutant->Header.Size);
ASSERT(Mutant->ApcDisable == 0);
/* Uncondtionally abandon it */ /* Make sure it's not terminating with APCs off */
if (Mutant->ApcDisable)
{
/* Bugcheck the system */
KEBUGCHECKEX(0,//THREAD_TERMINATE_HELD_MUTEX,
(ULONG_PTR)Thread,
(ULONG_PTR)Mutant,
0,
0);
}
/* Now we can remove it */
RemoveEntryList(&Mutant->MutantListEntry);
/* Unconditionally abandon it */
DPRINT("Abandonning the Mutant\n"); DPRINT("Abandonning the Mutant\n");
Mutant->Header.SignalState = 1; Mutant->Header.SignalState = 1;
Mutant->Abandoned = TRUE; Mutant->Abandoned = TRUE;
@ -479,12 +497,15 @@ KeRundownThread(VOID)
/* Check if the Wait List isn't empty */ /* Check if the Wait List isn't empty */
DPRINT("Checking whether to wake the Mutant\n"); DPRINT("Checking whether to wake the Mutant\n");
if (!IsListEmpty(&Mutant->Header.WaitListHead)) { if (!IsListEmpty(&Mutant->Header.WaitListHead))
{
/* Wake the Mutant */ /* Wake the Mutant */
DPRINT("Waking the Mutant\n"); DPRINT("Waking the Mutant\n");
KiWaitTest(&Mutant->Header, MUTANT_INCREMENT); KiWaitTest(&Mutant->Header, MUTANT_INCREMENT);
} }
/* Move on */
NextEntry = NextEntry->Flink;
} }
/* Release the Lock */ /* Release the Lock */