- Invert CONFIG_SMP defines as requested by Hartmut
[reactos.git] / reactos / ntoskrnl / ke / kthread.c
index 2c54c4e..57c775c 100644 (file)
@@ -172,48 +172,22 @@ KiDispatchThreadNoLock(ULONG NewThreadStatus)
     KEBUGCHECK(0);
 }
 
-VOID
-STDCALL
-KiBlockThread(PNTSTATUS Status,
-              UCHAR Alertable,
-              ULONG WaitMode,
-              UCHAR WaitReason)
+NTSTATUS
+NTAPI
+KiSwapThread(VOID)
 {
-    PKTHREAD Thread = KeGetCurrentThread();
-    PKWAIT_BLOCK WaitBlock;
-
-    if (Thread->ApcState.KernelApcPending) {
-
-        DPRINT("Dispatching Thread as ready (APC!)\n");
-
-        /* Remove Waits */
-        WaitBlock = Thread->WaitBlockList;
-        do {
-            RemoveEntryList (&WaitBlock->WaitListEntry);
-            WaitBlock = WaitBlock->NextWaitBlock;
-        } while (WaitBlock != Thread->WaitBlockList);
-        Thread->WaitBlockList = NULL;
-
-        /* Dispatch it and return status */
-        KiDispatchThreadNoLock (Ready);
-        if (Status != NULL) *Status = STATUS_KERNEL_APC;
-
-    } else {
+    PKTHREAD CurrentThread = KeGetCurrentThread();
 
-        /* Set the Thread Data as Requested */
-        DPRINT("Dispatching Thread as blocked: %d\n", Thread->WaitStatus);
-        Thread->Alertable = Alertable;
-        Thread->WaitMode = (UCHAR)WaitMode;
-        Thread->WaitReason = WaitReason;
+    /* Find a new thread to run */
+    DPRINT("Dispatching Thread as blocked\n");
+    KiDispatchThreadNoLock(Waiting);
 
-        /* Dispatch it and return status */
-        KiDispatchThreadNoLock(Waiting);
-        DPRINT("Dispatching Thread as blocked: %d\n", Thread->WaitStatus);
-        if (Status != NULL) *Status = Thread->WaitStatus;
-    }
+    /* Lower IRQL back */
+    DPRINT("Lowering IRQL \n");
+    KfLowerIrql(CurrentThread->WaitIrql);
 
-    DPRINT("Releasing Dispatcher Lock\n");
-    KfLowerIrql(Thread->WaitIrql);
+    /* Return the wait status */
+    return CurrentThread->WaitStatus;
 }
 
 VOID
@@ -456,22 +430,43 @@ 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;
@@ -479,12 +474,15 @@ KeRundownThread(VOID)
 
         /* 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 */
@@ -795,7 +793,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",
@@ -1153,15 +1151,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;
@@ -1235,7 +1230,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 */
@@ -1279,7 +1273,6 @@ KeSetPriorityThread(PKTHREAD Thread,
 
     /* Reset the Quantum and Decrements */
     Thread->Quantum = Thread->QuantumReset;
-    Thread->DecrementCount = 0;
     Thread->PriorityDecrement = 0;
 
     /* Set the new Priority */
@@ -1333,7 +1326,7 @@ KeSetAffinityThread(PKTHREAD Thread,
 
         if (Thread->State == Running) {
 
-            ProcessorMask = 1 << KeGetCurrentKPCR()->Number;
+            ProcessorMask = 1 << KeGetCurrentProcessorNumber();
             if (Thread == KeGetCurrentThread()) {
 
                 if (!(Affinity & ProcessorMask)) {