- Replaced MP with CONFIG_SMP.
- Implemented an idle processor map.
- Fixed the initialisation of the first kernel stack for the application processors.
Modified: trunk/reactos/ntoskrnl/ke/main.c
Modified: trunk/reactos/ntoskrnl/ps/thread.c

Modified: trunk/reactos/ntoskrnl/ke/main.c
--- trunk/reactos/ntoskrnl/ke/main.c	2005-01-05 19:25:49 UTC (rev 12832)
+++ trunk/reactos/ntoskrnl/ke/main.c	2005-01-05 19:26:51 UTC (rev 12833)
@@ -518,11 +518,7 @@
       PsPrepareForApplicationProcessorInit(KeNumberProcessors);
 
       /* Allocate a stack for use when booting the processor */
-      /* FIXME: The nonpaged memory for the stack is not released after use */
-      ProcessorStack = 
-	(char*)ExAllocatePool(NonPagedPool, MM_STACK_SIZE) + MM_STACK_SIZE;
-      Ki386InitialStackArray[((int)KeNumberProcessors)] = 
-	(PVOID)((char*)ProcessorStack - MM_STACK_SIZE);
+      ProcessorStack = Ki386InitialStackArray[((int)KeNumberProcessors)] + MM_STACK_SIZE;
 
       HalStartNextProcessor(0, (ULONG)ProcessorStack - 2*sizeof(FX_SAVE_AREA));
       KeNumberProcessors++;

Modified: trunk/reactos/ntoskrnl/ps/thread.c
--- trunk/reactos/ntoskrnl/ps/thread.c	2005-01-05 19:25:49 UTC (rev 12832)
+++ trunk/reactos/ntoskrnl/ps/thread.c	2005-01-05 19:26:51 UTC (rev 12833)
@@ -34,11 +34,14 @@
 
 LONG PiNrThreadsAwaitingReaping = 0;
 
+extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
+
 /*
  * PURPOSE: List of threads associated with each priority level
  */
 static LIST_ENTRY PriorityListHead[MAXIMUM_PRIORITY];
 static ULONG PriorityListMask = 0;
+static ULONG IdleProcessorMask = 0;
 static BOOLEAN DoneInitYet = FALSE;
 static KEVENT PiReaperThreadEvent;
 static BOOLEAN PiReaperThreadShouldTerminate = FALSE;
@@ -56,7 +59,7 @@
  */
 PKTHREAD STDCALL KeGetCurrentThread(VOID)
 {
-#ifdef MP
+#ifdef CONFIG_SMP
    ULONG Flags;
    PKTHREAD Thread;
    Ke386SaveFlags(Flags);
@@ -299,8 +302,10 @@
          Thread = CONTAINING_RECORD(AThread, ETHREAD, ThreadListEntry);
 
          nThreads++;
-         DbgPrint("Thread->Tcb.State %d PID.TID %d.%d Name %.8s Stack: \n",
+         DbgPrint("Thread->Tcb.State %d Affinity %08x Priority %d PID.TID %d.%d Name %.8s Stack: \n",
                   Thread->Tcb.State,
+		  Thread->Tcb.Affinity,
+		  Thread->Tcb.Priority,
                   Thread->ThreadsProcess->UniqueProcessId,
                   Thread->Cid.UniqueThread,
                   Thread->ThreadsProcess->ImageFileName);
@@ -425,6 +430,7 @@
 	if (Candidate != NULL)
 	  {
 	    PETHREAD OldThread;
+	    PKTHREAD IdleThread;
 
 	    DPRINT("Scheduling %x(%d)\n",Candidate, CurrentPriority);
 
@@ -432,7 +438,17 @@
 
 	    OldThread = CurrentThread;
 	    CurrentThread = Candidate;
+	    IdleThread = KeGetCurrentKPCR()->PrcbData.IdleThread;
 
+	    if (&OldThread->Tcb == IdleThread)
+	    {
+	       IdleProcessorMask &= ~Affinity;
+	    }
+	    else if (&CurrentThread->Tcb == IdleThread)
+	    {
+	       IdleProcessorMask |= Affinity;
+	    }
+
 	    MmUpdatePageDir(PsGetCurrentProcess(),(PVOID)CurrentThread->ThreadsProcess, sizeof(EPROCESS));
 
 	    KiArchContextSwitch(&CurrentThread->Tcb, &OldThread->Tcb);
@@ -475,12 +491,41 @@
     }
   else
     {
+      ULONG Processor;
+      KAFFINITY Affinity;
       if (WaitStatus != NULL)
 	{
 	  Thread->Tcb.WaitStatus = *WaitStatus;
 	}
       Thread->Tcb.State = THREAD_STATE_READY;
       PsInsertIntoThreadList(Thread->Tcb.Priority, Thread);
+      Processor = KeGetCurrentProcessorNumber();
+      Affinity = Thread->Tcb.Affinity;
+      if (!(IdleProcessorMask & (1 << Processor) & Affinity) &&
+          (IdleProcessorMask & ~(1 << Processor) & Affinity))
+        {
+	  ULONG i;
+	  for (i = 0; i < KeNumberProcessors - 1; i++)
+	    {
+	      Processor++;
+	      if (Processor >= KeNumberProcessors)
+	        {
+	          Processor = 0;
+	        }
+	      if (IdleProcessorMask & (1 << Processor) & Affinity)
+	        {
+#if 0	        
+                  /* FIXME:
+                   *   Reschedule the threads on an other processor 
+                   */
+		  KeReleaseDispatcherDatabaseLockFromDpcLevel();
+                  KiRequestReschedule(Processor);
+		  KeAcquireDispatcherDatabaseLockAtDpcLevel();
+#endif
+	          break;
+		}
+	    }
+	} 
     }
 }
 
@@ -634,6 +679,10 @@
 VOID
 PsApplicationProcessorInit(VOID)
 {
+   KIRQL oldIrql;
+   oldIrql = KeAcquireDispatcherDatabaseLock();
+   IdleProcessorMask |= (1 << KeGetCurrentProcessorNumber());
+   KeReleaseDispatcherDatabaseLock(oldIrql);
 }
 
 VOID INIT_FUNCTION
@@ -648,7 +697,7 @@
 		     &IdleThreadHandle,
 		     THREAD_ALL_ACCESS,
 		     NULL,
-		     TRUE);
+		     FALSE);
   IdleThread->Tcb.State = THREAD_STATE_RUNNING;
   IdleThread->Tcb.FreezeCount = 0;
   IdleThread->Tcb.Affinity = 1 << Id;
@@ -657,6 +706,9 @@
   IdleThread->Tcb.BasePriority = LOW_PRIORITY;
   Pcr->PrcbData.IdleThread = &IdleThread->Tcb;
   Pcr->PrcbData.CurrentThread = &IdleThread->Tcb;
+
+  Ki386InitialStackArray[Id] = (PVOID)IdleThread->Tcb.StackLimit;
+
   NtClose(IdleThreadHandle);
   DPRINT("IdleThread for Processor %d has PID %d\n",
 	   Id, IdleThread->Cid.UniqueThread);