- Optimized the dispatcher lock. It is now gone on non-SMP systems and IRQL is raised...
[reactos.git] / reactos / ntoskrnl / ke / kthread.c
index c3b58f0..b473e47 100644 (file)
@@ -456,36 +456,59 @@ KeRundownThread(VOID)
 {
     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 */
@@ -796,7 +819,7 @@ KeInitializeThread(PKPROCESS Process,
     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",
@@ -1154,15 +1177,12 @@ KiSetPriorityThread(PKTHREAD Thread,
 }
 
 /*
- * 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;
@@ -1236,7 +1256,6 @@ KeSetBasePriorityThread (PKTHREAD Thread,
     Thread->BasePriority = BasePriority;
 
     /* Reset the decrements */
-    Thread->DecrementCount = 0;
     Thread->PriorityDecrement = 0;
 
     /* If the priority will change, reset quantum and change it for real */
@@ -1280,7 +1299,6 @@ KeSetPriorityThread(PKTHREAD Thread,
 
     /* Reset the Quantum and Decrements */
     Thread->Quantum = Thread->QuantumReset;
-    Thread->DecrementCount = 0;
     Thread->PriorityDecrement = 0;
 
     /* Set the new Priority */
@@ -1334,7 +1352,7 @@ KeSetAffinityThread(PKTHREAD Thread,
 
         if (Thread->State == Running) {
 
-            ProcessorMask = 1 << KeGetCurrentKPCR()->Number;
+            ProcessorMask = 1 << KeGetCurrentProcessorNumber();
             if (Thread == KeGetCurrentThread()) {
 
                 if (!(Affinity & ProcessorMask)) {