- Replaced PiThreadLock with the dispatcher databae lock.

- Fixed some problems while setting/changing the affinity of a thread.

svn path=/trunk/; revision=12045
This commit is contained in:
Hartmut Birr 2004-12-12 17:25:53 +00:00
parent 6d37ab99d0
commit 973ea3b0bc
6 changed files with 84 additions and 59 deletions

View file

@ -200,8 +200,7 @@ _Ki386ContextSwitch:
*/
sti
push $_PiThreadLock
call _KeReleaseSpinLockFromDpcLevel@4
call _KeReleaseDispatcherDatabaseLockFromDpcLevel
cmpl $0, _PiNrThreadsAwaitingReaping
je 5f

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.58 2004/11/10 02:50:59 ion Exp $
/* $Id: kthread.c,v 1.59 2004/12/12 17:25:52 hbirr Exp $
*
* FILE: ntoskrnl/ke/kthread.c
* PURPOSE: Microkernel thread support
@ -312,12 +312,25 @@ KeRevertToUserAffinityThread(VOID)
{
PKTHREAD CurrentThread;
CurrentThread = KeGetCurrentThread();
ASSERT(CurrentThread->SystemAffinityActive != FALSE);
/* Return to User Affinity */
CurrentThread->Affinity = CurrentThread->UserAffinity;
/* Disable System Affinity */
CurrentThread->SystemAffinityActive = FALSE;
if (CurrentThread->Affinity & (1 << KeGetCurrentProcessorNumber()))
{
KeReleaseDispatcherDatabaseLock(oldIrql);
}
else
{
CurrentThread->WaitIrql = oldIrql;
PsDispatchThreadNoLock(THREAD_STATE_READY);
KeLowerIrql(oldIrql);
}
}
/*
@ -349,13 +362,31 @@ STDCALL
KeSetSystemAffinityThread(IN KAFFINITY Affinity)
{
PKTHREAD CurrentThread;
KIRQL oldIrql;
oldIrql = KeAcquireDispatcherDatabaseLock();
CurrentThread = KeGetCurrentThread();
ASSERT(CurrentThread->SystemAffinityActive == FALSE);
ASSERT(Affinity & ((1 << KeNumberProcessors) - 1));
/* Set the System Affinity Specified */
/* Set the System Affinity Specified */
CurrentThread->Affinity = Affinity;
/* Enable System Affinity */
CurrentThread->SystemAffinityActive = TRUE;
if (Affinity & (1 << KeGetCurrentProcessorNumber()))
{
KeReleaseDispatcherDatabaseLock(oldIrql);
}
else
{
CurrentThread->WaitIrql = oldIrql;
PsDispatchThreadNoLock(THREAD_STATE_READY);
KeLowerIrql(oldIrql);
}
}
/*

View file

@ -79,8 +79,18 @@ VOID
KeReleaseDispatcherDatabaseLock(KIRQL OldIrql)
{
DPRINT("KeReleaseDispatcherDatabaseLock(OldIrql %x)\n",OldIrql);
KeReleaseSpinLock(&DispatcherDatabaseLock, OldIrql);
if (!KeIsExecutingDpc() &&
OldIrql < DISPATCH_LEVEL &&
KeGetCurrentThread() != NULL &&
KeGetCurrentThread() == KeGetCurrentKPCR()->PrcbData.IdleThread)
{
PsDispatchThreadNoLock(THREAD_STATE_READY);
KeLowerIrql(OldIrql);
}
else
{
KeReleaseSpinLock(&DispatcherDatabaseLock, OldIrql);
}
}

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.87 2004/12/10 16:50:37 navaraf Exp $
/* $Id: create.c,v 1.88 2004/12/12 17:25:52 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -27,8 +27,6 @@
/* GLOBAL *******************************************************************/
extern KSPIN_LOCK PiThreadLock;
#define MAX_THREAD_NOTIFY_ROUTINE_COUNT 8
static ULONG PiThreadNotifyRoutineCount = 0;
@ -460,10 +458,10 @@ PsInitializeThread(PEPROCESS Process,
Thread->LpcExitThreadCalled = FALSE;
Thread->LpcReceivedMsgIdValid = FALSE;
KeAcquireSpinLock(&PiThreadLock, &oldIrql);
oldIrql = KeAcquireDispatcherDatabaseLock();
InsertTailList(&Process->ThreadListHead,
&Thread->ThreadListEntry);
KeReleaseSpinLock(&PiThreadLock, oldIrql);
KeReleaseDispatcherDatabaseLock(oldIrql);
*ThreadPtr = Thread;

View file

@ -1,4 +1,4 @@
/* $Id: kill.c,v 1.89 2004/12/04 16:56:20 blight Exp $
/* $Id: kill.c,v 1.90 2004/12/12 17:25:52 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -17,8 +17,6 @@
/* GLOBALS *******************************************************************/
extern KSPIN_LOCK PiThreadLock;
VOID PsTerminateCurrentThread(NTSTATUS ExitStatus);
NTSTATUS STDCALL NtCallTerminatePorts(PETHREAD Thread);
@ -41,19 +39,17 @@ PsReapThreads(VOID)
PETHREAD Thread;
PLIST_ENTRY ListEntry;
KeAcquireSpinLock(&PiThreadLock, &oldlvl);
oldlvl = KeAcquireDispatcherDatabaseLock();
while((ListEntry = RemoveHeadList(&ThreadsToReapHead)) != &ThreadsToReapHead)
{
PiNrThreadsAwaitingReaping--;
KeReleaseSpinLock(&PiThreadLock, oldlvl);
KeReleaseDispatcherDatabaseLock(oldlvl);
Thread = CONTAINING_RECORD(ListEntry, ETHREAD, TerminationPortList);
ObDereferenceObject(Thread);
KeAcquireSpinLock(&PiThreadLock, &oldlvl);
oldlvl = KeAcquireDispatcherDatabaseLock();
}
KeReleaseSpinLock(&PiThreadLock, oldlvl);
KeReleaseDispatcherDatabaseLock(oldlvl);
}
VOID
@ -73,9 +69,9 @@ PiTerminateProcessThreads(PEPROCESS Process,
DPRINT("PiTerminateProcessThreads(Process %x, ExitStatus %x)\n",
Process, ExitStatus);
oldlvl = KeAcquireDispatcherDatabaseLock();
KeAcquireSpinLock(&PiThreadLock, &oldlvl);
current_entry = Process->ThreadListHead.Flink;
while (current_entry != &Process->ThreadListHead)
{
@ -86,9 +82,9 @@ PiTerminateProcessThreads(PEPROCESS Process,
DPRINT("Terminating %x, current thread: %x, "
"thread's process: %x\n", current, PsGetCurrentThread(),
current->ThreadsProcess);
KeReleaseSpinLock(&PiThreadLock, oldlvl);
KeReleaseDispatcherDatabaseLock(oldlvl);
PsTerminateOtherThread(current, ExitStatus);
KeAcquireSpinLock(&PiThreadLock, &oldlvl);
oldlvl = KeAcquireDispatcherDatabaseLock();
current_entry = Process->ThreadListHead.Flink;
}
else
@ -96,7 +92,7 @@ PiTerminateProcessThreads(PEPROCESS Process,
current_entry = current_entry->Flink;
}
}
KeReleaseSpinLock(&PiThreadLock, oldlvl);
KeReleaseDispatcherDatabaseLock(oldlvl);
DPRINT("Finished PiTerminateProcessThreads()\n");
}
@ -131,7 +127,7 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus)
KeCancelTimer(&CurrentThread->Tcb.Timer);
KeAcquireSpinLock(&PiThreadLock, &oldIrql);
oldIrql = KeAcquireDispatcherDatabaseLock();
DPRINT("terminating %x\n",CurrentThread);
@ -145,7 +141,7 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus)
InterlockedCompareExchangePointer(&KeGetCurrentKPCR()->PrcbData.NpxThread,
NULL, ETHREAD_TO_KTHREAD(CurrentThread));
KeReleaseSpinLock(&PiThreadLock, oldIrql);
KeReleaseDispatcherDatabaseLock(oldIrql);
PsLockProcess(CurrentProcess, FALSE);
@ -209,7 +205,7 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus)
PiTerminateProcess(CurrentProcess, ExitStatus);
}
KeAcquireSpinLock(&PiThreadLock, &oldIrql);
oldIrql = KeAcquireDispatcherDatabaseLock();
#ifdef _ENABLE_THRDEVTPAIR
ExpSwapThreadEventPair(CurrentThread, NULL); /* Release the associated eventpair object, if there was one */
@ -260,14 +256,14 @@ PsTerminateOtherThread(PETHREAD Thread,
DPRINT("PsTerminateOtherThread(Thread %x, ExitStatus %x)\n",
Thread, ExitStatus);
KeAcquireSpinLock(&PiThreadLock, &OldIrql);
OldIrql = KeAcquireDispatcherDatabaseLock();
if (Thread->HasTerminated)
{
KeReleaseSpinLock(&PiThreadLock, OldIrql);
KeReleaseDispatcherDatabaseLock (OldIrql);
return;
}
Thread->HasTerminated = TRUE;
KeReleaseSpinLock(&PiThreadLock, OldIrql);
KeReleaseDispatcherDatabaseLock (OldIrql);
Thread->ExitStatus = ExitStatus;
Apc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG_TERMINATE_APC);
KeInitializeApc(Apc,

View file

@ -1,4 +1,4 @@
/* $Id: thread.c,v 1.140 2004/12/10 16:50:37 navaraf Exp $
/* $Id: thread.c,v 1.141 2004/12/12 17:25:53 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -32,7 +32,6 @@ extern LIST_ENTRY PsProcessListHead;
POBJECT_TYPE EXPORTED PsThreadType = NULL;
KSPIN_LOCK PiThreadLock;
LONG PiNrThreadsAwaitingReaping = 0;
/*
@ -338,10 +337,10 @@ static PETHREAD PsScanThreadList(KPRIORITY Priority, ULONG Affinity)
DPRINT1("%d/%d\n", current->Cid.UniqueThread, current->Tcb.State);
}
ASSERT(current->Tcb.State == THREAD_STATE_READY);
DPRINT("current->Tcb.UserAffinity %x Affinity %x PID %d %d\n",
current->Tcb.UserAffinity, Affinity, current->Cid.UniqueThread,
DPRINT("current->Tcb.Affinity %x Affinity %x PID %d %d\n",
current->Tcb.Affinity, Affinity, current->Cid.UniqueThread,
Priority);
if (current->Tcb.UserAffinity & Affinity)
if (current->Tcb.Affinity & Affinity)
{
PsRemoveFromThreadList(current);
return(current);
@ -408,7 +407,7 @@ VOID PsDispatchThreadNoLock (ULONG NewThreadStatus)
if (Candidate == CurrentThread)
{
Candidate->Tcb.State = THREAD_STATE_RUNNING;
KeReleaseSpinLockFromDpcLevel(&PiThreadLock);
KeReleaseDispatcherDatabaseLockFromDpcLevel();
return;
}
if (Candidate != NULL)
@ -441,8 +440,7 @@ PsDispatchThread(ULONG NewThreadStatus)
{
return;
}
KeAcquireSpinLock(&PiThreadLock, &oldIrql);
oldIrql = KeAcquireDispatcherDatabaseLock();
/*
* Save wait IRQL
*/
@ -454,9 +452,6 @@ PsDispatchThread(ULONG NewThreadStatus)
VOID
PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus)
{
KIRQL oldIrql;
KeAcquireSpinLock(&PiThreadLock, &oldIrql);
if (THREAD_STATE_TERMINATED_1 == Thread->Tcb.State ||
THREAD_STATE_TERMINATED_2 == Thread->Tcb.State)
{
@ -478,7 +473,6 @@ PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus)
Thread->Tcb.State = THREAD_STATE_READY;
PsInsertIntoThreadList(Thread->Tcb.Priority, Thread);
}
KeReleaseSpinLock(&PiThreadLock, oldIrql);
}
VOID
@ -493,11 +487,6 @@ PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
if (!DispatcherLock)
{
oldIrql = KeAcquireDispatcherDatabaseLock();
KiAcquireSpinLock(&PiThreadLock);
}
else
{
KeAcquireSpinLock(&PiThreadLock, &oldIrql);
}
KThread = KeGetCurrentThread();
@ -511,7 +500,6 @@ PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
WaitBlock = WaitBlock->NextWaitBlock;
}
Thread->Tcb.WaitBlockList = NULL;
KeReleaseDispatcherDatabaseLockFromDpcLevel();
PsDispatchThreadNoLock (THREAD_STATE_READY);
if (Status != NULL)
{
@ -520,7 +508,6 @@ PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
}
else
{
KeReleaseDispatcherDatabaseLockFromDpcLevel();
Thread->Tcb.Alertable = Alertable;
Thread->Tcb.WaitMode = (UCHAR)WaitMode;
Thread->Tcb.WaitIrql = WaitIrql;
@ -546,8 +533,7 @@ PsFreezeAllThreads(PEPROCESS Process)
PLIST_ENTRY current_entry;
PETHREAD current;
KeAcquireSpinLock(&PiThreadLock, &oldIrql);
oldIrql = KeAcquireDispatcherDatabaseLock();
current_entry = Process->ThreadListHead.Flink;
while (current_entry != &Process->ThreadListHead)
{
@ -562,7 +548,7 @@ PsFreezeAllThreads(PEPROCESS Process)
current_entry = current_entry->Flink;
}
KeReleaseSpinLock(&PiThreadLock, oldIrql);
KeReleaseDispatcherDatabaseLock(oldIrql);
}
ULONG
@ -572,7 +558,7 @@ PsEnumThreadsByProcess(PEPROCESS Process)
PLIST_ENTRY current_entry;
ULONG Count = 0;
KeAcquireSpinLock(&PiThreadLock, &oldIrql);
oldIrql = KeAcquireDispatcherDatabaseLock();
current_entry = Process->ThreadListHead.Flink;
while (current_entry != &Process->ThreadListHead)
@ -581,7 +567,7 @@ PsEnumThreadsByProcess(PEPROCESS Process)
current_entry = current_entry->Flink;
}
KeReleaseSpinLock(&PiThreadLock, oldIrql);
KeReleaseDispatcherDatabaseLock(oldIrql);
return Count;
}
@ -657,6 +643,7 @@ PsPrepareForApplicationProcessorInit(ULONG Id)
TRUE);
IdleThread->Tcb.State = THREAD_STATE_RUNNING;
IdleThread->Tcb.FreezeCount = 0;
IdleThread->Tcb.Affinity = 1 << Id;
IdleThread->Tcb.UserAffinity = 1 << Id;
IdleThread->Tcb.Priority = LOW_PRIORITY;
Pcr->PrcbData.IdleThread = &IdleThread->Tcb;
@ -678,7 +665,6 @@ PsInitThreadManagment(VOID)
HANDLE FirstThreadHandle;
NTSTATUS Status;
KeInitializeSpinLock(&PiThreadLock);
for (i=0; i < MAXIMUM_PRIORITY; i++)
{
InitializeListHead(&PriorityListHead[i]);
@ -713,6 +699,8 @@ PsInitThreadManagment(VOID)
THREAD_ALL_ACCESS,NULL, TRUE);
FirstThread->Tcb.State = THREAD_STATE_RUNNING;
FirstThread->Tcb.FreezeCount = 0;
FirstThread->Tcb.UserAffinity = (1 << 0); /* Set the affinity of the first thread to the boot processor */
FirstThread->Tcb.Affinity = (1 << 0);
KeGetCurrentKPCR()->PrcbData.CurrentThread = (PVOID)FirstThread;
NtClose(FirstThreadHandle);
@ -791,7 +779,7 @@ KeSetPriorityThread (PKTHREAD Thread, KPRIORITY Priority)
KEBUGCHECK(0);
}
KeAcquireSpinLock(&PiThreadLock, &oldIrql);
oldIrql = KeAcquireDispatcherDatabaseLock();
OldPriority = Thread->Priority;
Thread->BasePriority = Thread->Priority = (CHAR)Priority;
@ -825,7 +813,7 @@ KeSetPriorityThread (PKTHREAD Thread, KPRIORITY Priority)
}
}
}
KeReleaseSpinLock(&PiThreadLock, oldIrql);
KeReleaseDispatcherDatabaseLock(oldIrql);
return(OldPriority);
}
@ -861,6 +849,7 @@ NtAlertThread (IN HANDLE ThreadHandle)
PETHREAD Thread;
NTSTATUS Status;
NTSTATUS ThreadStatus;
KIRQL oldIrql;
Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_SUSPEND_RESUME,
@ -874,7 +863,9 @@ NtAlertThread (IN HANDLE ThreadHandle)
}
ThreadStatus = STATUS_ALERTED;
oldIrql = KeAcquireDispatcherDatabaseLock();
(VOID)PsUnblockThread(Thread, &ThreadStatus);
KeReleaseDispatcherDatabaseLock(oldIrql);
ObDereferenceObject(Thread);
return(STATUS_SUCCESS);