- 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;
}