{
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);
+
+ /* 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);
+ }
- /* Uncondtionally abandon it */
+ /* Now we can remove it */
+ RemoveEntryList(&Mutant->MutantListEntry);
+
+ /* Unconditionally abandon it */
DPRINT("Abandonning the Mutant\n");
Mutant->Header.SignalState = 1;
Mutant->Abandoned = TRUE;
Mutant->OwnerThread = NULL;
- RemoveEntryList(&Mutant->MutantListEntry);
/* 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 */
DPRINT("Initializing Dispatcher Header for New Thread: %x in Process: %x\n", Thread, Process);
KeInitializeDispatcherHeader(&Thread->DispatcherHeader,
ThreadObject,
- sizeof(KTHREAD),
+ sizeof(KTHREAD) / sizeof(LONG),
FALSE);
DPRINT("Thread Header Created. SystemRoutine: %x, StartRoutine: %x with Context: %x\n",
}
/*
- * Sets thread's base priority relative to the process' base priority
- * Should only be passed in THREAD_PRIORITY_ constants in pstypes.h
- *
* @implemented
*/
LONG
STDCALL
-KeSetBasePriorityThread (PKTHREAD Thread,
- LONG Increment)
+KeSetBasePriorityThread(PKTHREAD Thread,
+ LONG Increment)
{
KIRQL OldIrql;
PKPROCESS Process;
Thread->BasePriority = BasePriority;
/* Reset the decrements */
- Thread->DecrementCount = 0;
Thread->PriorityDecrement = 0;
/* If the priority will change, reset quantum and change it for real */
/* Reset the Quantum and Decrements */
Thread->Quantum = Thread->QuantumReset;
- Thread->DecrementCount = 0;
Thread->PriorityDecrement = 0;
/* Set the new Priority */
if (Thread->State == Running) {
- ProcessorMask = 1 << KeGetCurrentKPCR()->Number;
+ ProcessorMask = 1 << KeGetCurrentProcessorNumber();
if (Thread == KeGetCurrentThread()) {
if (!(Affinity & ProcessorMask)) {