- 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.

svn path=/trunk/; revision=12694
This commit is contained in:
Hartmut Birr 2005-01-01 11:47:33 +00:00
parent 879287ceb0
commit 2e5a5b050c
8 changed files with 137 additions and 61 deletions

View file

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

View file

@ -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
}
/*

View file

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

View file

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

View file

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

View file

@ -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);

View file

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

View file

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