diff --git a/reactos/ntoskrnl/ke/event.c b/reactos/ntoskrnl/ke/event.c index 8f536fd39c4..b352142f623 100644 --- a/reactos/ntoskrnl/ke/event.c +++ b/reactos/ntoskrnl/ke/event.c @@ -98,7 +98,7 @@ LONG STDCALL KeSetEvent (PKEVENT Event, else { KTHREAD *Thread = KeGetCurrentThread(); - Thread->WaitNext = Wait; + Thread->WaitNext = TRUE; Thread->WaitIrql = OldIrql; } @@ -128,7 +128,7 @@ NTSTATUS STDCALL KePulseEvent (PKEVENT Event, else { KTHREAD *Thread = KeGetCurrentThread(); - Thread->WaitNext = Wait; + Thread->WaitNext = TRUE; Thread->WaitIrql = OldIrql; } diff --git a/reactos/ntoskrnl/ke/kthread.c b/reactos/ntoskrnl/ke/kthread.c index 63f9a4a801f..b74fc265b51 100644 --- a/reactos/ntoskrnl/ke/kthread.c +++ b/reactos/ntoskrnl/ke/kthread.c @@ -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 @@ KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First) 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 @@ VOID STDCALL KeRevertToUserAffinityThread(VOID) { +#ifdef MP PKTHREAD CurrentThread; KIRQL oldIrql; @@ -335,6 +336,7 @@ KeRevertToUserAffinityThread(VOID) PsDispatchThreadNoLock(THREAD_STATE_READY); KeLowerIrql(oldIrql); } +#endif } /* @@ -365,6 +367,7 @@ VOID STDCALL KeSetSystemAffinityThread(IN KAFFINITY Affinity) { +#ifdef MP PKTHREAD CurrentThread; KIRQL oldIrql; @@ -372,7 +375,6 @@ KeSetSystemAffinityThread(IN KAFFINITY Affinity) CurrentThread = KeGetCurrentThread(); - ASSERT(CurrentThread->SystemAffinityActive == FALSE); ASSERT(Affinity & ((1 << KeNumberProcessors) - 1)); /* Set the System Affinity Specified */ @@ -391,6 +393,7 @@ KeSetSystemAffinityThread(IN KAFFINITY Affinity) PsDispatchThreadNoLock(THREAD_STATE_READY); KeLowerIrql(oldIrql); } +#endif } /* diff --git a/reactos/ntoskrnl/ke/main.c b/reactos/ntoskrnl/ke/main.c index 62f95c35740..022904b09bc 100644 --- a/reactos/ntoskrnl/ke/main.c +++ b/reactos/ntoskrnl/ke/main.c @@ -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 @@ ExpInitializeExecutive(VOID) 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 @@ ExpInitializeExecutive(VOID) 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 @@ ExpInitializeExecutive(VOID) if (!SeInit2()) KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED); + KeNumberProcessors = 1; + PiInitProcessManager(); if (KdPollBreakIn ()) @@ -509,8 +511,6 @@ ExpInitializeExecutive(VOID) } /* Initialize all processors */ - KeNumberProcessors = 1; - while (!HalAllProcessorsStarted()) { PVOID ProcessorStack; diff --git a/reactos/ntoskrnl/ke/mutex.c b/reactos/ntoskrnl/ke/mutex.c index 539638a8dc3..841b44d3ddf 100644 --- a/reactos/ntoskrnl/ke/mutex.c +++ b/reactos/ntoskrnl/ke/mutex.c @@ -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 @@ KeReleaseMutex(IN PKMUTEX Mutex, else { KTHREAD *Thread = KeGetCurrentThread(); - Thread->WaitNext = Wait; + Thread->WaitNext = TRUE; Thread->WaitIrql = OldIrql; } @@ -201,7 +201,7 @@ KeReleaseMutant(IN PKMUTANT Mutant, else { KTHREAD *Thread = KeGetCurrentThread(); - Thread->WaitNext = Wait; + Thread->WaitNext = TRUE; Thread->WaitIrql = OldIrql; } diff --git a/reactos/ntoskrnl/ke/sem.c b/reactos/ntoskrnl/ke/sem.c index 1ed2eb9935d..f3b226b4456 100644 --- a/reactos/ntoskrnl/ke/sem.c +++ b/reactos/ntoskrnl/ke/sem.c @@ -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 @@ KeReleaseSemaphore (PKSEMAPHORE Semaphore, else { KTHREAD *Thread = KeGetCurrentThread(); - Thread->WaitNext = Wait; + Thread->WaitNext = TRUE; Thread->WaitIrql = OldIrql; } diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 7ee33300f2b..89c0c048b6f 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -730,13 +730,21 @@ KeWaitForMultipleObjects(ULONG Count, 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); diff --git a/reactos/ntoskrnl/ps/idle.c b/reactos/ntoskrnl/ps/idle.c index db169cd695e..6fec7c96b30 100644 --- a/reactos/ntoskrnl/ps/idle.c +++ b/reactos/ntoskrnl/ps/idle.c @@ -50,8 +50,6 @@ PsIdleThreadMain(PVOID Context) VOID INIT_FUNCTION PsInitIdleThread(VOID) { - KPRIORITY Priority; - ULONG Affinity; NTSTATUS Status; PETHREAD IdleThread; HANDLE IdleThreadHandle; @@ -63,39 +61,27 @@ PsInitIdleThread(VOID) 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); + } diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 654b53432b8..6004132814f 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -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 @@ -242,10 +242,21 @@ PsIsThreadImpersonating( return Thread->ActiveImpersonationInfo; } +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 @@ VOID PsDumpThreads(BOOLEAN IncludeSystem) { 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 @@ VOID PsDumpThreads(BOOLEAN IncludeSystem) Ebp = (PULONG)Ebp[0]; i++; } - if((i % 8) != 7) + if((i % 8) != 0) { DbgPrint("\n"); } @@ -427,7 +438,8 @@ VOID PsDispatchThreadNoLock (ULONG NewThreadStatus) 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 @@ PsDispatchThread(ULONG NewThreadStatus) return; } oldIrql = KeAcquireDispatcherDatabaseLock(); - /* - * Save wait IRQL - */ - KeGetCurrentThread()->WaitIrql = oldIrql; PsDispatchThreadNoLock(NewThreadStatus); KeLowerIrql(oldIrql); } @@ -510,7 +518,6 @@ PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode, { 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 @@ PsPrepareForApplicationProcessorInit(ULONG Id) 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 @@ KeSetPriorityThread (PKTHREAD Thread, KPRIORITY Priority) KIRQL oldIrql; PKTHREAD CurrentThread; ULONG Mask; + int i; + PKPCR Pcr; if (Priority < LOW_PRIORITY || Priority >= MAXIMUM_PRIORITY) { @@ -782,15 +792,15 @@ KeSetPriorityThread (PKTHREAD Thread, KPRIORITY Priority) 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 @@ KeSetPriorityThread (PKTHREAD Thread, KPRIORITY Priority) } 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 @@ KeSetPriorityThread (PKTHREAD Thread, KPRIORITY Priority) */ 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,,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; }