- Simplified KeSetSystemAffinityThread and KeRevertToUserAffinityThread for non smp machines.  
- Set the number of processors before calling PiInitProcessManager.  
- Lock the dispatcher database while accessing some values in the thread structure in KeWaitForMultipleObjects.  
- Used Ke-functions to initialize the idle thread.  
- Fixed the offset to the stack frame in PsDumpThreads.  
- Implemented KeSetAffinityThread.  
- Fixed KeSetPriorityThread for threads on the ready queue.
Modified: trunk/reactos/ntoskrnl/ke/event.c
Modified: trunk/reactos/ntoskrnl/ke/kthread.c
Modified: trunk/reactos/ntoskrnl/ke/main.c
Modified: trunk/reactos/ntoskrnl/ke/mutex.c
Modified: trunk/reactos/ntoskrnl/ke/sem.c
Modified: trunk/reactos/ntoskrnl/ke/wait.c
Modified: trunk/reactos/ntoskrnl/ps/idle.c
Modified: trunk/reactos/ntoskrnl/ps/thread.c

Modified: trunk/reactos/ntoskrnl/ke/event.c
--- trunk/reactos/ntoskrnl/ke/event.c	2005-01-01 11:42:12 UTC (rev 12693)
+++ trunk/reactos/ntoskrnl/ke/event.c	2005-01-01 11:47:33 UTC (rev 12694)
@@ -98,7 +98,7 @@
   else
     {
       KTHREAD *Thread = KeGetCurrentThread();
-      Thread->WaitNext = Wait;
+      Thread->WaitNext = TRUE;
       Thread->WaitIrql = OldIrql;
     }
 
@@ -128,7 +128,7 @@
   else
     {
       KTHREAD *Thread = KeGetCurrentThread();
-      Thread->WaitNext = Wait;
+      Thread->WaitNext = TRUE;
       Thread->WaitIrql = OldIrql;
     }
 

Modified: trunk/reactos/ntoskrnl/ke/kthread.c
--- trunk/reactos/ntoskrnl/ke/kthread.c	2005-01-01 11:42:12 UTC (rev 12693)
+++ trunk/reactos/ntoskrnl/ke/kthread.c	2005-01-01 11:47:33 UTC (rev 12694)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: kthread.c,v 1.61 2004/12/12 23:18:55 navaraf Exp $
+/* $Id$
  *
  * FILE:            ntoskrnl/ke/kthread.c
  * PURPOSE:         Microkernel thread support
@@ -237,9 +237,9 @@
   Thread->ApcState.UserApcPending = 0;
   Thread->ContextSwitches = 0;
   Thread->WaitStatus = STATUS_SUCCESS;
-  Thread->WaitIrql = 0;
+  Thread->WaitIrql = PASSIVE_LEVEL;
   Thread->WaitMode = 0;
-  Thread->WaitNext = 0;
+  Thread->WaitNext = FALSE;
   Thread->WaitBlockList = NULL;
   Thread->WaitListEntry.Flink = NULL;
   Thread->WaitListEntry.Blink = NULL;
@@ -310,6 +310,7 @@
 STDCALL
 KeRevertToUserAffinityThread(VOID)
 {
+#ifdef MP
 	PKTHREAD CurrentThread;
 	KIRQL oldIrql;
 
@@ -335,6 +336,7 @@
            PsDispatchThreadNoLock(THREAD_STATE_READY);
            KeLowerIrql(oldIrql);
 	}
+#endif
 }
 
 /*
@@ -365,6 +367,7 @@
 STDCALL
 KeSetSystemAffinityThread(IN KAFFINITY Affinity)
 {
+#ifdef MP
 	PKTHREAD CurrentThread;
 	KIRQL oldIrql;
 
@@ -372,7 +375,6 @@
 
 	CurrentThread = KeGetCurrentThread();
 
-	ASSERT(CurrentThread->SystemAffinityActive == FALSE);
 	ASSERT(Affinity & ((1 << KeNumberProcessors) - 1));
 	
         /* Set the System Affinity Specified */
@@ -391,6 +393,7 @@
            PsDispatchThreadNoLock(THREAD_STATE_READY);
            KeLowerIrql(oldIrql);
 	}
+#endif
 }
 
 /*

Modified: trunk/reactos/ntoskrnl/ke/main.c
--- trunk/reactos/ntoskrnl/ke/main.c	2005-01-01 11:42:12 UTC (rev 12693)
+++ trunk/reactos/ntoskrnl/ke/main.c	2005-01-01 11:47:33 UTC (rev 12694)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: main.c,v 1.212 2004/12/24 17:06:58 navaraf Exp $
+/* $Id$
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/main.c
@@ -461,10 +461,10 @@
 
   KeInit2();
   
-#if 1
+#if 0
   if (KeMemoryMapRangeCount > 0)
     {
-      DPRINT("MemoryMap:\n");
+      DPRINT1("MemoryMap:\n");
       for (i = 0; i < KeMemoryMapRangeCount; i++)
         {
           switch(KeMemoryMap[i].Type)
@@ -484,7 +484,7 @@
 	      default:
 	        sprintf(str, "type %lu", KeMemoryMap[i].Type);
             }
-          DPRINT("%08x - %08x %s\n", KeMemoryMap[i].BaseAddrLow, KeMemoryMap[i].BaseAddrLow + KeMemoryMap[i].LengthLow, str);
+          DPRINT1("%08x - %08x %s\n", KeMemoryMap[i].BaseAddrLow, KeMemoryMap[i].BaseAddrLow + KeMemoryMap[i].LengthLow, str);
 	}
     }
 #endif
@@ -501,6 +501,8 @@
   if (!SeInit2())
     KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED);
 
+  KeNumberProcessors = 1;
+
   PiInitProcessManager();
 
   if (KdPollBreakIn ())
@@ -509,8 +511,6 @@
     }
 
   /* Initialize all processors */
-  KeNumberProcessors = 1;
-
   while (!HalAllProcessorsStarted())
     {
       PVOID ProcessorStack;

Modified: trunk/reactos/ntoskrnl/ke/mutex.c
--- trunk/reactos/ntoskrnl/ke/mutex.c	2005-01-01 11:42:12 UTC (rev 12693)
+++ trunk/reactos/ntoskrnl/ke/mutex.c	2005-01-01 11:47:33 UTC (rev 12694)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: mutex.c,v 1.19 2004/11/21 18:33:54 gdalsnes Exp $
+/* $Id$
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/mutex.c
@@ -92,7 +92,7 @@
   else
     {
       KTHREAD *Thread = KeGetCurrentThread();
-      Thread->WaitNext = Wait;
+      Thread->WaitNext = TRUE;
       Thread->WaitIrql = OldIrql;
     }
 
@@ -201,7 +201,7 @@
   else
     {
       KTHREAD *Thread = KeGetCurrentThread();
-      Thread->WaitNext = Wait;
+      Thread->WaitNext = TRUE;
       Thread->WaitIrql = OldIrql;
     }
 

Modified: trunk/reactos/ntoskrnl/ke/sem.c
--- trunk/reactos/ntoskrnl/ke/sem.c	2005-01-01 11:42:12 UTC (rev 12693)
+++ trunk/reactos/ntoskrnl/ke/sem.c	2005-01-01 11:47:33 UTC (rev 12694)
@@ -16,7 +16,7 @@
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
-/* $Id: sem.c,v 1.16 2004/11/21 18:33:54 gdalsnes Exp $
+/* $Id$
  *
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/sem.c
@@ -115,7 +115,7 @@
   else
     {
       KTHREAD *Thread = KeGetCurrentThread();
-      Thread->WaitNext = Wait;
+      Thread->WaitNext = TRUE;
       Thread->WaitIrql = OldIrql;
     }
 

Modified: trunk/reactos/ntoskrnl/ke/wait.c
--- trunk/reactos/ntoskrnl/ke/wait.c	2005-01-01 11:42:12 UTC (rev 12693)
+++ trunk/reactos/ntoskrnl/ke/wait.c	2005-01-01 11:47:33 UTC (rev 12694)
@@ -730,14 +730,22 @@
       PsBlockThread(&Status, Alertable, WaitMode, TRUE, OldIrql, (UCHAR)WaitReason);
 
       //kernel queues
-      //FIXME: dispatcher lock not held here!
+      OldIrql = KeAcquireDispatcherDatabaseLock ();
       if (CurrentThread->Queue && WaitReason != WrQueue)
       {
          DPRINT("queue: wake from something else\n");
          CurrentThread->Queue->CurrentCount++;
       }
+      if (Status == STATUS_KERNEL_APC)
+      {
+         CurrentThread->WaitNext = TRUE;
+         CurrentThread->WaitIrql = OldIrql;
+      }
+      else
+      {
+         KeReleaseDispatcherDatabaseLock(OldIrql);
+      }
       
-      
    } while (Status == STATUS_KERNEL_APC);
    
 

Modified: trunk/reactos/ntoskrnl/ps/idle.c
--- trunk/reactos/ntoskrnl/ps/idle.c	2005-01-01 11:42:12 UTC (rev 12693)
+++ trunk/reactos/ntoskrnl/ps/idle.c	2005-01-01 11:47:33 UTC (rev 12694)
@@ -50,8 +50,6 @@
 VOID INIT_FUNCTION
 PsInitIdleThread(VOID)
 {
-   KPRIORITY Priority;
-   ULONG Affinity;
    NTSTATUS Status;
    PETHREAD IdleThread;
    HANDLE IdleThreadHandle;
@@ -63,39 +61,27 @@
 			NULL,
 			PsIdleThreadMain,
 			NULL);
-   if(!NT_SUCCESS(Status)) {
+   if(!NT_SUCCESS(Status)) 
+   {
 	DPRINT("Couldn't create Idle System Thread!");
 	KEBUGCHECK(0);
 	return;
    }   
-
-   Priority = LOW_PRIORITY;
-   Status = NtSetInformationThread(IdleThreadHandle,
-			  ThreadPriority,
-			  &Priority,
-			  sizeof(Priority));
-   if(!NT_SUCCESS(Status)) {
-	DPRINT("Couldn't set Priority to Idle System Thread!");
-	return;
-   }
-   
-   Affinity = 1 << 0;
-   Status = NtSetInformationThread(IdleThreadHandle,
-			  ThreadAffinityMask,
-			  &Affinity,
-			  sizeof(Affinity));
-   if(!NT_SUCCESS(Status)) {
-	DPRINT("Couldn't set Affinity Mask to Idle System Thread!");
-   }
    Status = ObReferenceObjectByHandle(IdleThreadHandle,
 				      THREAD_ALL_ACCESS,
 				      PsThreadType,
 				      KernelMode,
 				      (PVOID*)&IdleThread,
 				      NULL);
-   if(!NT_SUCCESS(Status)) {
+   if(!NT_SUCCESS(Status)) 
+   {
 	DPRINT("Couldn't get pointer to Idle System Thread!");
+	KEBUGCHECK(0);
+	return;
    }
-   KeGetCurrentKPCR()->PrcbData.IdleThread = &IdleThread->Tcb;
    NtClose(IdleThreadHandle);
+   KeGetCurrentKPCR()->PrcbData.IdleThread = &IdleThread->Tcb;
+   KeSetPriorityThread(&IdleThread->Tcb, LOW_PRIORITY);
+   KeSetAffinityThread(&IdleThread->Tcb, 1 << 0);
+
 }

Modified: trunk/reactos/ntoskrnl/ps/thread.c
--- trunk/reactos/ntoskrnl/ps/thread.c	2005-01-01 11:42:12 UTC (rev 12693)
+++ trunk/reactos/ntoskrnl/ps/thread.c	2005-01-01 11:47:33 UTC (rev 12694)
@@ -1,4 +1,4 @@
-/* $Id: thread.c,v 1.141 2004/12/12 17:25:53 hbirr Exp $
+/* $Id$
  *
  * COPYRIGHT:              See COPYING in the top level directory
  * PROJECT:                ReactOS kernel
@@ -243,9 +243,20 @@
 }
 
 static VOID
+KiRequestReschedule(CCHAR Processor)
+{
+   PKPCR Pcr;
+
+   Pcr = (PKPCR)(KPCR_BASE + Processor * PAGE_SIZE);
+   Pcr->PrcbData.QuantumEnd = TRUE;
+   KiIpiSendRequest(1 << Processor, IPI_REQUEST_DPC);
+}
+
+static VOID
 PsInsertIntoThreadList(KPRIORITY Priority, PETHREAD Thread)
 {
    ASSERT(THREAD_STATE_READY == Thread->Tcb.State);
+   ASSERT(Thread->Tcb.Priority == Priority);
    if (Priority >= MAXIMUM_PRIORITY || Priority < LOW_PRIORITY)
      {
 	DPRINT1("Invalid thread priority (%d)\n", Priority);
@@ -298,7 +309,7 @@
          {
            ULONG i = 0;
            PULONG Esp = (PULONG)Thread->Tcb.KernelStack;
-           PULONG Ebp = (PULONG)Esp[3];
+           PULONG Ebp = (PULONG)Esp[4];
            DbgPrint("Ebp 0x%.8X\n", Ebp);
            while(Ebp != 0 && Ebp >= (PULONG)Thread->Tcb.StackLimit)
            {
@@ -306,7 +317,7 @@
              Ebp = (PULONG)Ebp[0];
              i++;
            }
-           if((i % 8) != 7)
+           if((i % 8) != 0)
            {
              DbgPrint("\n");
            }
@@ -427,7 +438,8 @@
 	    return;
 	  }
      }
-   CPRINT("CRITICAL: No threads are ready\n");
+   CPRINT("CRITICAL: No threads are ready (CPU%d)\n", KeGetCurrentProcessorNumber());
+   PsDumpThreads(TRUE);
    KEBUGCHECK(0);
 }
 
@@ -441,10 +453,6 @@
 	return;
      }
    oldIrql = KeAcquireDispatcherDatabaseLock();
-   /*
-    * Save wait IRQL
-    */
-   KeGetCurrentThread()->WaitIrql = oldIrql;
    PsDispatchThreadNoLock(NewThreadStatus);
    KeLowerIrql(oldIrql);
 }
@@ -510,7 +518,6 @@
     {
       Thread->Tcb.Alertable = Alertable;
       Thread->Tcb.WaitMode = (UCHAR)WaitMode;
-      Thread->Tcb.WaitIrql = WaitIrql;
       Thread->Tcb.WaitReason = WaitReason;
       PsDispatchThreadNoLock(THREAD_STATE_BLOCKED);
 
@@ -646,6 +653,7 @@
   IdleThread->Tcb.Affinity = 1 << Id;
   IdleThread->Tcb.UserAffinity = 1 << Id;
   IdleThread->Tcb.Priority = LOW_PRIORITY;
+  IdleThread->Tcb.BasePriority = LOW_PRIORITY;
   Pcr->PrcbData.IdleThread = &IdleThread->Tcb;
   Pcr->PrcbData.CurrentThread = &IdleThread->Tcb;
   NtClose(IdleThreadHandle);
@@ -773,6 +781,8 @@
    KIRQL oldIrql;
    PKTHREAD CurrentThread;
    ULONG Mask;
+   int i;
+   PKPCR Pcr;
 
    if (Priority < LOW_PRIORITY || Priority >= MAXIMUM_PRIORITY)
      {
@@ -782,15 +792,15 @@
    oldIrql = KeAcquireDispatcherDatabaseLock();
 
    OldPriority = Thread->Priority;
-   Thread->BasePriority = Thread->Priority = (CHAR)Priority;
 
    if (OldPriority != Priority)
      {
+       CurrentThread = KeGetCurrentThread();
        if (Thread->State == THREAD_STATE_READY)
          {
 	   PsRemoveFromThreadList((PETHREAD)Thread);
+           Thread->BasePriority = Thread->Priority = (CHAR)Priority;
 	   PsInsertIntoThreadList(Priority, (PETHREAD)Thread);
-	   CurrentThread = KeGetCurrentThread();
 	   if (CurrentThread->Priority < Priority)
 	     {
                PsDispatchThreadNoLock(THREAD_STATE_READY);
@@ -800,18 +810,40 @@
 	 }
        else if (Thread->State == THREAD_STATE_RUNNING)
          {
+           Thread->BasePriority = Thread->Priority = (CHAR)Priority;
 	   if (Priority < OldPriority)
 	     {
 	       /* Check for threads with a higher priority */
 	       Mask = ~((1 << (Priority + 1)) - 1);
 	       if (PriorityListMask & Mask)
 	         {
-                   PsDispatchThreadNoLock(THREAD_STATE_READY);
-                   KeLowerIrql(oldIrql);
-	           return (OldPriority);
+		   if (Thread == CurrentThread)
+		     {
+                       PsDispatchThreadNoLock(THREAD_STATE_READY);
+                       KeLowerIrql(oldIrql);
+	               return (OldPriority);
+		     }
+		   else
+		     {
+		       for (i = 0; i < KeNumberProcessors; i++)
+		       {
+		          Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE);
+			  if (Pcr->PrcbData.CurrentThread == Thread)
+			  {
+			    KeReleaseDispatcherDatabaseLockFromDpcLevel();
+                            KiRequestReschedule(i);
+                            KeLowerIrql(oldIrql);
+	                    return (OldPriority);
+			  }
+		       }
+		     }
 		 }
 	     }
 	 }
+       else
+         {
+            Thread->BasePriority = Thread->Priority = (CHAR)Priority;
+         }
      }
    KeReleaseDispatcherDatabaseLock(oldIrql);
    return(OldPriority);
@@ -822,14 +854,61 @@
  */
 NTSTATUS STDCALL
 KeSetAffinityThread(PKTHREAD	Thread,
-		    PVOID	AfMask)
+		    KAFFINITY	Affinity)
 /*
  * Sets thread's affinity
  */
 {
-	DPRINT1("KeSetAffinityThread() is a stub returning STATUS_SUCCESS");
-	return STATUS_SUCCESS; // FIXME: Use function below
-	//return ZwSetInformationThread(handle, ThreadAffinityMask,<pointer to affinity mask>,sizeof(KAFFINITY));
+    KIRQL oldIrql;
+    ULONG i;
+    PKPCR Pcr;
+    KAFFINITY ProcessorMask;
+
+    DPRINT("KeSetAffinityThread(Thread %x, Affinity %x)\n", Thread, Affinity);
+
+    ASSERT(Affinity & ((1 << KeNumberProcessors) - 1));
+
+    oldIrql = KeAcquireDispatcherDatabaseLock();
+
+    Thread->UserAffinity = Affinity;
+    if (Thread->SystemAffinityActive == FALSE)
+    {
+       Thread->Affinity = Affinity;
+       if (Thread->State == THREAD_STATE_RUNNING)
+       {
+          ProcessorMask = 1 << KeGetCurrentKPCR()->ProcessorNumber;
+          if (Thread == KeGetCurrentThread())
+	  {
+	     if (!(Affinity & ProcessorMask))
+	     {
+                PsDispatchThreadNoLock(THREAD_STATE_READY);
+                KeLowerIrql(oldIrql);
+		return STATUS_SUCCESS;
+	     }
+	  }
+	  else
+	  {
+	     for (i = 0; i < KeNumberProcessors; i++)
+	     {
+		Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE);
+		if (Pcr->PrcbData.CurrentThread == Thread)
+		{
+		   if (!(Affinity & ProcessorMask))
+		   {
+		      KeReleaseDispatcherDatabaseLockFromDpcLevel();
+                      KiRequestReschedule(i);
+                      KeLowerIrql(oldIrql);
+		      return STATUS_SUCCESS;
+		   }
+		   break;
+		}
+	     }
+	     ASSERT (i < KeNumberProcessors);
+	  }
+       }
+    }
+    KeReleaseDispatcherDatabaseLock(oldIrql);
+    return STATUS_SUCCESS;
 }