- 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).
Modified: trunk/reactos/ntoskrnl/ke/kthread.c
_____
Modified: trunk/reactos/ntoskrnl/ke/kthread.c
--- trunk/reactos/ntoskrnl/ke/kthread.c 2005-10-01 00:36:17 UTC (rev
18182)
+++ trunk/reactos/ntoskrnl/ke/kthread.c 2005-10-01 07:37:13 UTC (rev
18183)
@@ -456,22 +456,40 @@
{
KIRQL OldIrql;
PKTHREAD Thread = KeGetCurrentThread();
- PLIST_ENTRY CurrentEntry;
+ PLIST_ENTRY NextEntry, ListHead;
PKMUTANT Mutant;
-
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 */
OldIrql = KeAcquireDispatcherDatabaseLock();
- while (!IsListEmpty(&Thread->MutantListHead)) {
-
+ /* Get the List Pointers */
+ ListHead = &Thread->MutantListHead;
+ NextEntry = ListHead->Flink;
+ while (NextEntry != ListHead)
+ {
/* Get the Mutant */
- CurrentEntry = RemoveHeadList(&Thread->MutantListHead);
- Mutant = CONTAINING_RECORD(CurrentEntry, KMUTANT,
MutantListEntry);
- ASSERT(Mutant->ApcDisable == 0);
+ Mutant = CONTAINING_RECORD(NextEntry, KMUTANT,
MutantListEntry);
+ DPRINT1("Mutant: %p. Type, Size %x %x\n", Mutant,
Mutant->Header.Type, Mutant->Header.Size);
- /* 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");
Mutant->Header.SignalState = 1;
Mutant->Abandoned = TRUE;
@@ -479,12 +497,15 @@
/* Check if the Wait List isn't empty */
DPRINT("Checking whether to wake the Mutant\n");
- if (!IsListEmpty(&Mutant->Header.WaitListHead)) {
-
+ if (!IsListEmpty(&Mutant->Header.WaitListHead))
+ {
/* Wake the Mutant */
DPRINT("Waking the Mutant\n");
KiWaitTest(&Mutant->Header, MUTANT_INCREMENT);
}
+
+ /* Move on */
+ NextEntry = NextEntry->Flink;
}
/* Release the Lock */
Show replies by date