Reimplemented dispatcher database lock and synchronization primitives.

This fixes bug #26.

svn path=/trunk/; revision=6502
This commit is contained in:
Eric Kohl 2003-11-02 01:16:21 +00:00
parent de4f0fd8ab
commit df0af98c1b
9 changed files with 213 additions and 119 deletions

View file

@ -44,8 +44,11 @@ VOID STDCALL KeRescheduleThread();
VOID KiUpdateSystemTime (KIRQL oldIrql, ULONG Eip); VOID KiUpdateSystemTime (KIRQL oldIrql, ULONG Eip);
VOID KeAcquireDispatcherDatabaseLock(BOOLEAN Wait); KIRQL KeAcquireDispatcherDatabaseLock(VOID);
VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait); VOID KeAcquireDispatcherDatabaseLockAtDpcLevel(VOID);
VOID KeReleaseDispatcherDatabaseLock(KIRQL Irql);
VOID KeReleaseDispatcherDatabaseLockFromDpcLevel(VOID);
BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr); BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr);
VOID STDCALL KeExpireTimers(PKDPC Apc, VOID STDCALL KeExpireTimers(PKDPC Apc,
PVOID Arg1, PVOID Arg1,
@ -59,7 +62,6 @@ VOID KeRemoveAllWaitsThread(struct _ETHREAD* Thread, NTSTATUS WaitStatus, BOOL U
PULONG KeGetStackTopThread(struct _ETHREAD* Thread); PULONG KeGetStackTopThread(struct _ETHREAD* Thread);
VOID KeContextToTrapFrame(PCONTEXT Context, VOID KeContextToTrapFrame(PCONTEXT Context,
PKTRAP_FRAME TrapFrame); PKTRAP_FRAME TrapFrame);
VOID KeReleaseDispatcherDatabaseLockAtDpcLevel(BOOLEAN Wait);
VOID VOID
KiDeliverNormalApc(VOID); KiDeliverNormalApc(VOID);

View file

@ -13,6 +13,7 @@
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <internal/ke.h> #include <internal/ke.h>
#include <internal/id.h> #include <internal/id.h>
#include <internal/ps.h>
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
@ -80,14 +81,29 @@ LONG STDCALL KeSetEvent (PKEVENT Event,
KPRIORITY Increment, KPRIORITY Increment,
BOOLEAN Wait) BOOLEAN Wait)
{ {
int ret; KIRQL OldIrql;
int ret;
DPRINT("KeSetEvent(Event %x, Wait %x)\n",Event,Wait); DPRINT("KeSetEvent(Event %x, Wait %x)\n",Event,Wait);
KeAcquireDispatcherDatabaseLock(Wait);
ret = InterlockedExchange(&(Event->Header.SignalState),1); OldIrql = KeAcquireDispatcherDatabaseLock();
KeDispatcherObjectWake((DISPATCHER_HEADER *)Event);
KeReleaseDispatcherDatabaseLock(Wait); ret = InterlockedExchange(&(Event->Header.SignalState),1);
return(ret);
KeDispatcherObjectWake((DISPATCHER_HEADER *)Event);
if (Wait == FALSE)
{
KeReleaseDispatcherDatabaseLock(OldIrql);
}
else
{
KTHREAD *Thread = KeGetCurrentThread();
Thread->WaitNext = Wait;
Thread->WaitIrql = OldIrql;
}
return(ret);
} }
/* /*
@ -97,15 +113,27 @@ NTSTATUS STDCALL KePulseEvent (PKEVENT Event,
KPRIORITY Increment, KPRIORITY Increment,
BOOLEAN Wait) BOOLEAN Wait)
{ {
KIRQL OldIrql;
int ret; int ret;
DPRINT("KePulseEvent(Event %x, Wait %x)\n",Event,Wait); DPRINT("KePulseEvent(Event %x, Wait %x)\n",Event,Wait);
KeAcquireDispatcherDatabaseLock(Wait); OldIrql = KeAcquireDispatcherDatabaseLock();
ret = InterlockedExchange(&(Event->Header.SignalState),1); ret = InterlockedExchange(&(Event->Header.SignalState),1);
KeDispatcherObjectWake((DISPATCHER_HEADER *)Event); KeDispatcherObjectWake((DISPATCHER_HEADER *)Event);
InterlockedExchange(&(Event->Header.SignalState),0); InterlockedExchange(&(Event->Header.SignalState),0);
KeReleaseDispatcherDatabaseLock(Wait);
return((NTSTATUS)ret); if (Wait == FALSE)
{
KeReleaseDispatcherDatabaseLock(OldIrql);
}
else
{
KTHREAD *Thread = KeGetCurrentThread();
Thread->WaitNext = Wait;
Thread->WaitIrql = OldIrql;
}
return ((NTSTATUS)ret);
} }
/* EOF */ /* EOF */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: mutex.c,v 1.14 2003/07/21 21:53:51 royce Exp $ /* $Id: mutex.c,v 1.15 2003/11/02 01:15:15 ekohl Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/mutex.c * FILE: ntoskrnl/ke/mutex.c
@ -71,7 +71,9 @@ LONG STDCALL
KeReleaseMutex(IN PKMUTEX Mutex, KeReleaseMutex(IN PKMUTEX Mutex,
IN BOOLEAN Wait) IN BOOLEAN Wait)
{ {
KeAcquireDispatcherDatabaseLock(Wait); KIRQL OldIrql;
OldIrql = KeAcquireDispatcherDatabaseLock();
if (Mutex->OwnerThread != KeGetCurrentThread()) if (Mutex->OwnerThread != KeGetCurrentThread())
{ {
DbgPrint("THREAD_NOT_MUTEX_OWNER: Mutex %p\n", Mutex); DbgPrint("THREAD_NOT_MUTEX_OWNER: Mutex %p\n", Mutex);
@ -86,7 +88,18 @@ KeReleaseMutex(IN PKMUTEX Mutex,
RemoveEntryList(&Mutex->MutantListEntry); RemoveEntryList(&Mutex->MutantListEntry);
KeDispatcherObjectWake(&Mutex->Header); KeDispatcherObjectWake(&Mutex->Header);
} }
KeReleaseDispatcherDatabaseLock(Wait);
if (Wait == FALSE)
{
KeReleaseDispatcherDatabaseLock(OldIrql);
}
else
{
KTHREAD *Thread = KeGetCurrentThread();
Thread->WaitNext = Wait;
Thread->WaitIrql = OldIrql;
}
return(0); return(0);
} }
@ -153,7 +166,9 @@ KeReleaseMutant(IN PKMUTANT Mutant,
IN BOOLEAN Abandon, IN BOOLEAN Abandon,
IN BOOLEAN Wait) IN BOOLEAN Wait)
{ {
KeAcquireDispatcherDatabaseLock(Wait); KIRQL OldIrql;
OldIrql = KeAcquireDispatcherDatabaseLock();
if (Abandon == FALSE) if (Abandon == FALSE)
{ {
if (Mutant->OwnerThread != NULL && Mutant->OwnerThread != KeGetCurrentThread()) if (Mutant->OwnerThread != NULL && Mutant->OwnerThread != KeGetCurrentThread())
@ -183,7 +198,17 @@ KeReleaseMutant(IN PKMUTANT Mutant,
KeDispatcherObjectWake(&Mutant->Header); KeDispatcherObjectWake(&Mutant->Header);
} }
KeReleaseDispatcherDatabaseLock(Wait); if (Wait == FALSE)
{
KeReleaseDispatcherDatabaseLock(OldIrql);
}
else
{
KTHREAD *Thread = KeGetCurrentThread();
Thread->WaitNext = Wait;
Thread->WaitIrql = OldIrql;
}
return(0); return(0);
} }

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: queue.c,v 1.9 2003/08/14 18:30:28 silverblade Exp $ /* $Id: queue.c,v 1.10 2003/11/02 01:15:15 ekohl Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/queue.c * FILE: ntoskrnl/ke/queue.c
@ -75,10 +75,11 @@ KiInsertQueue(
) )
{ {
ULONG InitialState; ULONG InitialState;
KIRQL OldIrql;
DPRINT("KiInsertQueue(Queue %x, Entry %x)\n", Queue, Entry); DPRINT("KiInsertQueue(Queue %x, Entry %x)\n", Queue, Entry);
KeAcquireDispatcherDatabaseLock(FALSE); OldIrql = KeAcquireDispatcherDatabaseLock ();
InitialState = Queue->Header.SignalState; InitialState = Queue->Header.SignalState;
Queue->Header.SignalState++; Queue->Header.SignalState++;
@ -97,7 +98,7 @@ KiInsertQueue(
KeDispatcherObjectWake(&Queue->Header); KeDispatcherObjectWake(&Queue->Header);
} }
KeReleaseDispatcherDatabaseLock(FALSE); KeReleaseDispatcherDatabaseLock(OldIrql);
return InitialState; return InitialState;
} }
@ -136,8 +137,9 @@ KeRemoveQueue(IN PKQUEUE Queue,
PLIST_ENTRY ListEntry; PLIST_ENTRY ListEntry;
NTSTATUS Status; NTSTATUS Status;
PKTHREAD Thread = KeGetCurrentThread(); PKTHREAD Thread = KeGetCurrentThread();
KIRQL OldIrql;
KeAcquireDispatcherDatabaseLock(FALSE); OldIrql = KeAcquireDispatcherDatabaseLock ();
//assiciate new thread with queue? //assiciate new thread with queue?
if (Thread->Queue != Queue) if (Thread->Queue != Queue)
@ -158,12 +160,12 @@ KeRemoveQueue(IN PKQUEUE Queue,
{ {
ListEntry = RemoveHeadList(&Queue->EntryListHead); ListEntry = RemoveHeadList(&Queue->EntryListHead);
Queue->Header.SignalState--; Queue->Header.SignalState--;
KeReleaseDispatcherDatabaseLock(FALSE); KeReleaseDispatcherDatabaseLock (OldIrql);
return ListEntry; return ListEntry;
} }
//need to wait for it... //need to wait for it...
KeReleaseDispatcherDatabaseLock(FALSE); KeReleaseDispatcherDatabaseLock (OldIrql);
Status = KeWaitForSingleObject(Queue, Status = KeWaitForSingleObject(Queue,
WrQueue, WrQueue,
@ -177,9 +179,9 @@ KeRemoveQueue(IN PKQUEUE Queue,
} }
else else
{ {
KeAcquireDispatcherDatabaseLock(FALSE); OldIrql = KeAcquireDispatcherDatabaseLock ();
ListEntry = RemoveHeadList(&Queue->EntryListHead); ListEntry = RemoveHeadList(&Queue->EntryListHead);
KeReleaseDispatcherDatabaseLock(FALSE); KeReleaseDispatcherDatabaseLock (OldIrql);
return ListEntry; return ListEntry;
} }
@ -194,12 +196,13 @@ KeRundownQueue(IN PKQUEUE Queue)
{ {
PLIST_ENTRY EnumEntry; PLIST_ENTRY EnumEntry;
PKTHREAD Thread; PKTHREAD Thread;
KIRQL OldIrql;
DPRINT("KeRundownQueue(Queue %x)\n", Queue); DPRINT("KeRundownQueue(Queue %x)\n", Queue);
//FIXME: should we wake thread waiting on a queue? //FIXME: should we wake thread waiting on a queue?
KeAcquireDispatcherDatabaseLock(FALSE); OldIrql = KeAcquireDispatcherDatabaseLock ();
// Clear Queue and QueueListEntry members of all threads associated with this queue // Clear Queue and QueueListEntry members of all threads associated with this queue
while (!IsListEmpty(&Queue->ThreadListHead)) while (!IsListEmpty(&Queue->ThreadListHead))
@ -215,7 +218,7 @@ KeRundownQueue(IN PKQUEUE Queue)
else else
EnumEntry = NULL; EnumEntry = NULL;
KeReleaseDispatcherDatabaseLock(FALSE); KeReleaseDispatcherDatabaseLock (OldIrql);
return EnumEntry; return EnumEntry;
} }

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: sem.c,v 1.13 2003/07/10 17:44:06 royce Exp $ /* $Id: sem.c,v 1.14 2003/11/02 01:15:15 ekohl Exp $
* *
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/sem.c * FILE: ntoskrnl/ke/sem.c
@ -30,6 +30,7 @@
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <internal/ke.h> #include <internal/ke.h>
#include <internal/ps.h>
#include <internal/id.h> #include <internal/id.h>
#define NDEBUG #define NDEBUG
@ -40,7 +41,7 @@
/* /*
* @implemented * @implemented
*/ */
VOID STDCALL VOID STDCALL
KeInitializeSemaphore (PKSEMAPHORE Semaphore, KeInitializeSemaphore (PKSEMAPHORE Semaphore,
LONG Count, LONG Count,
LONG Limit) LONG Limit)
@ -55,7 +56,7 @@ KeInitializeSemaphore (PKSEMAPHORE Semaphore,
/* /*
* @implemented * @implemented
*/ */
LONG STDCALL LONG STDCALL
KeReadStateSemaphore (PKSEMAPHORE Semaphore) KeReadStateSemaphore (PKSEMAPHORE Semaphore)
{ {
return(Semaphore->Header.SignalState); return(Semaphore->Header.SignalState);
@ -64,7 +65,7 @@ KeReadStateSemaphore (PKSEMAPHORE Semaphore)
/* /*
* @implemented * @implemented
*/ */
LONG STDCALL LONG STDCALL
KeReleaseSemaphore (PKSEMAPHORE Semaphore, KeReleaseSemaphore (PKSEMAPHORE Semaphore,
KPRIORITY Increment, KPRIORITY Increment,
LONG Adjustment, LONG Adjustment,
@ -90,27 +91,38 @@ KeReleaseSemaphore (PKSEMAPHORE Semaphore,
* object is Not-Signaled. * object is Not-Signaled.
*/ */
{ {
ULONG InitialState; ULONG InitialState;
KIRQL OldIrql;
DPRINT("KeReleaseSemaphore(Semaphore %x, Increment %d, Adjustment %d, "
DPRINT("KeReleaseSemaphore(Semaphore %x, Increment %d, Adjustment %d, "
"Wait %d)\n", Semaphore, Increment, Adjustment, Wait); "Wait %d)\n", Semaphore, Increment, Adjustment, Wait);
KeAcquireDispatcherDatabaseLock(Wait); OldIrql = KeAcquireDispatcherDatabaseLock();
InitialState = Semaphore->Header.SignalState; InitialState = Semaphore->Header.SignalState;
if (Semaphore->Limit < (LONG) InitialState + Adjustment || if (Semaphore->Limit < (LONG) InitialState + Adjustment ||
InitialState > InitialState + Adjustment) InitialState > InitialState + Adjustment)
{ {
ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED); ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
} }
Semaphore->Header.SignalState += Adjustment; Semaphore->Header.SignalState += Adjustment;
if (InitialState == 0) if (InitialState == 0)
{ {
KeDispatcherObjectWake(&Semaphore->Header); KeDispatcherObjectWake(&Semaphore->Header);
} }
KeReleaseDispatcherDatabaseLock(Wait); if (Wait == FALSE)
{
KeReleaseDispatcherDatabaseLock(OldIrql);
}
else
{
KTHREAD *Thread = KeGetCurrentThread();
Thread->WaitNext = Wait;
Thread->WaitIrql = OldIrql;
}
return(InitialState); return(InitialState);
} }

View file

@ -1,4 +1,4 @@
/* $Id: timer.c,v 1.62 2003/10/12 17:05:45 hbirr Exp $ /* $Id: timer.c,v 1.63 2003/11/02 01:15:15 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -400,6 +400,8 @@ KeQueryTickCount(PLARGE_INTEGER TickCount)
STATIC VOID STATIC VOID
HandleExpiredTimer(PKTIMER current) HandleExpiredTimer(PKTIMER current)
{ {
KIRQL OldIrql;
DPRINT("HandleExpiredTime(current %x)\n",current); DPRINT("HandleExpiredTime(current %x)\n",current);
if (current->Dpc != NULL) if (current->Dpc != NULL)
{ {
@ -410,10 +412,10 @@ HandleExpiredTimer(PKTIMER current)
NULL); NULL);
DPRINT("Finished dpc routine\n"); DPRINT("Finished dpc routine\n");
} }
KeAcquireDispatcherDatabaseLock(FALSE); OldIrql = KeAcquireDispatcherDatabaseLock ();
current->Header.SignalState = TRUE; current->Header.SignalState = TRUE;
KeDispatcherObjectWake(&current->Header); KeDispatcherObjectWake(&current->Header);
KeReleaseDispatcherDatabaseLock(FALSE); KeReleaseDispatcherDatabaseLock (OldIrql);
if (current->Period != 0) if (current->Period != 0)
{ {
current->DueTime.QuadPart += current->DueTime.QuadPart +=

View file

@ -29,9 +29,6 @@
/* GLOBALS ******************************************************************/ /* GLOBALS ******************************************************************/
static KSPIN_LOCK DispatcherDatabaseLock; static KSPIN_LOCK DispatcherDatabaseLock;
static BOOLEAN WaitSet = FALSE;
static KIRQL oldlvl = PASSIVE_LEVEL;
static PKTHREAD Owner = NULL;
#define KeDispatcherObjectWakeOne(hdr) KeDispatcherObjectWakeOneOrAll(hdr, FALSE) #define KeDispatcherObjectWakeOne(hdr) KeDispatcherObjectWakeOneOrAll(hdr, FALSE)
#define KeDispatcherObjectWakeAll(hdr) KeDispatcherObjectWakeOneOrAll(hdr, TRUE) #define KeDispatcherObjectWakeAll(hdr) KeDispatcherObjectWakeOneOrAll(hdr, TRUE)
@ -51,41 +48,52 @@ VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header,
InitializeListHead(&(Header->WaitListHead)); InitializeListHead(&(Header->WaitListHead));
} }
VOID KeAcquireDispatcherDatabaseLock(BOOLEAN Wait)
KIRQL
KeAcquireDispatcherDatabaseLock(VOID)
/* /*
* PURPOSE: Acquires the dispatcher database lock for the caller * PURPOSE: Acquires the dispatcher database lock for the caller
*/ */
{ {
DPRINT("KeAcquireDispatcherDatabaseLock(Wait %x)\n",Wait); KIRQL OldIrql;
if (WaitSet && Owner == KeGetCurrentThread())
{ DPRINT("KeAcquireDispatcherDatabaseLock()\n");
return;
} KeAcquireSpinLock (&DispatcherDatabaseLock, &OldIrql);
KeAcquireSpinLock(&DispatcherDatabaseLock, &oldlvl); return OldIrql;
WaitSet = Wait;
Owner = KeGetCurrentThread();
} }
VOID KeReleaseDispatcherDatabaseLockAtDpcLevel(BOOLEAN Wait)
VOID
KeAcquireDispatcherDatabaseLockAtDpcLevel(VOID)
/*
* PURPOSE: Acquires the dispatcher database lock for the caller
*/
{ {
DPRINT("KeReleaseDispatcherDatabaseLockAtDpcLevel(Wait %x) WaitSet=%x\n", Wait, WaitSet); DPRINT("KeAcquireDispatcherDatabaseLockAtDpcLevel()\n");
if (Wait == WaitSet)
{ KeAcquireSpinLockAtDpcLevel (&DispatcherDatabaseLock);
Owner = NULL;
KeReleaseSpinLockFromDpcLevel(&DispatcherDatabaseLock);
}
} }
VOID KeReleaseDispatcherDatabaseLock(BOOLEAN Wait)
VOID
KeReleaseDispatcherDatabaseLock(KIRQL OldIrql)
{ {
DPRINT("KeReleaseDispatcherDatabaseLock(Wait %x) WaitSet=%x\n",Wait,WaitSet); DPRINT("KeReleaseDispatcherDatabaseLock(OldIrql %x)\n",OldIrql);
if (Wait == WaitSet)
{ KeReleaseSpinLock(&DispatcherDatabaseLock, OldIrql);
Owner = NULL;
KeReleaseSpinLock(&DispatcherDatabaseLock, oldlvl);
}
} }
VOID
KeReleaseDispatcherDatabaseLockFromDpcLevel(VOID)
{
DPRINT("KeReleaseDispatcherDatabaseLock()\n");
KeReleaseSpinLockFromDpcLevel(&DispatcherDatabaseLock);
}
static BOOLEAN static BOOLEAN
KiSideEffectsBeforeWake(DISPATCHER_HEADER * hdr, KiSideEffectsBeforeWake(DISPATCHER_HEADER * hdr,
PKTHREAD Thread) PKTHREAD Thread)
@ -190,8 +198,9 @@ VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus, BOOL Unblock)
{ {
PKWAIT_BLOCK WaitBlock, PrevWaitBlock; PKWAIT_BLOCK WaitBlock, PrevWaitBlock;
BOOLEAN WasWaiting = FALSE; BOOLEAN WasWaiting = FALSE;
KIRQL OldIrql;
KeAcquireDispatcherDatabaseLock(FALSE); OldIrql = KeAcquireDispatcherDatabaseLock ();
WaitBlock = (PKWAIT_BLOCK)Thread->Tcb.WaitBlockList; WaitBlock = (PKWAIT_BLOCK)Thread->Tcb.WaitBlockList;
if (WaitBlock != NULL) if (WaitBlock != NULL)
@ -216,7 +225,7 @@ VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus, BOOL Unblock)
PsUnblockThread(Thread, &WaitStatus); PsUnblockThread(Thread, &WaitStatus);
} }
KeReleaseDispatcherDatabaseLock(FALSE); KeReleaseDispatcherDatabaseLock (OldIrql);
} }
static BOOLEAN static BOOLEAN
@ -459,6 +468,7 @@ KeWaitForMultipleObjects(ULONG Count,
ULONG i; ULONG i;
NTSTATUS Status; NTSTATUS Status;
KIRQL WaitIrql; KIRQL WaitIrql;
KIRQL OldIrql;
BOOLEAN Abandoned; BOOLEAN Abandoned;
DPRINT("Entering KeWaitForMultipleObjects(Count %lu Object[] %p) " DPRINT("Entering KeWaitForMultipleObjects(Count %lu Object[] %p) "
@ -499,7 +509,16 @@ KeWaitForMultipleObjects(ULONG Count,
do do
{ {
KeAcquireDispatcherDatabaseLock(FALSE); if (CurrentThread->WaitNext)
{
OldIrql = CurrentThread->WaitIrql;
CurrentThread->WaitNext = 0;
CurrentThread->WaitIrql = PASSIVE_LEVEL;
}
else
{
OldIrql = KeAcquireDispatcherDatabaseLock ();
}
/* /*
* If we are going to wait alertably and a user apc is pending * If we are going to wait alertably and a user apc is pending
@ -507,7 +526,7 @@ KeWaitForMultipleObjects(ULONG Count,
*/ */
if (Alertable && KiTestAlert()) if (Alertable && KiTestAlert())
{ {
KeReleaseDispatcherDatabaseLock(FALSE); KeReleaseDispatcherDatabaseLock(OldIrql);
return (STATUS_USER_APC); return (STATUS_USER_APC);
} }
@ -533,7 +552,7 @@ KeWaitForMultipleObjects(ULONG Count,
KeCancelTimer(&CurrentThread->Timer); KeCancelTimer(&CurrentThread->Timer);
} }
KeReleaseDispatcherDatabaseLock(FALSE); KeReleaseDispatcherDatabaseLock(OldIrql);
DPRINT("One object is (already) signaled!\n"); DPRINT("One object is (already) signaled!\n");
if (Abandoned == TRUE) if (Abandoned == TRUE)
@ -560,7 +579,7 @@ KeWaitForMultipleObjects(ULONG Count,
KeCancelTimer(&CurrentThread->Timer); KeCancelTimer(&CurrentThread->Timer);
} }
KeReleaseDispatcherDatabaseLock(FALSE); KeReleaseDispatcherDatabaseLock(OldIrql);
DPRINT("All objects are (already) signaled!\n"); DPRINT("All objects are (already) signaled!\n");
if (Abandoned == TRUE) if (Abandoned == TRUE)
@ -574,7 +593,7 @@ KeWaitForMultipleObjects(ULONG Count,
//zero timeout is used for testing if the object(s) can be immediately acquired //zero timeout is used for testing if the object(s) can be immediately acquired
if (Timeout != NULL && Timeout->QuadPart == 0) if (Timeout != NULL && Timeout->QuadPart == 0)
{ {
KeReleaseDispatcherDatabaseLock(FALSE); KeReleaseDispatcherDatabaseLock(OldIrql);
return STATUS_TIMEOUT; return STATUS_TIMEOUT;
} }
@ -585,7 +604,7 @@ KeWaitForMultipleObjects(ULONG Count,
{ {
KiSideEffectsBeforeWake(&CurrentThread->Timer.Header, CurrentThread); KiSideEffectsBeforeWake(&CurrentThread->Timer.Header, CurrentThread);
KeCancelTimer(&CurrentThread->Timer); KeCancelTimer(&CurrentThread->Timer);
KeReleaseDispatcherDatabaseLock(FALSE); KeReleaseDispatcherDatabaseLock(OldIrql);
return (STATUS_TIMEOUT); return (STATUS_TIMEOUT);
} }

View file

@ -1,4 +1,4 @@
/* $Id: kill.c,v 1.65 2003/09/18 17:55:21 fireball Exp $ /* $Id: kill.c,v 1.66 2003/11/02 01:16:21 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -95,14 +95,14 @@ PsReapThreads(VOID)
if (current->Tcb.State == THREAD_STATE_TERMINATED_1) if (current->Tcb.State == THREAD_STATE_TERMINATED_1)
{ {
PEPROCESS Process = current->ThreadsProcess; PEPROCESS Process = current->ThreadsProcess;
NTSTATUS Status = current->ExitStatus; NTSTATUS Status = current->ExitStatus;
BOOLEAN Last; BOOLEAN Last;
PiNrThreadsAwaitingReaping--; PiNrThreadsAwaitingReaping--;
current->Tcb.State = THREAD_STATE_TERMINATED_2; current->Tcb.State = THREAD_STATE_TERMINATED_2;
RemoveEntryList(&current->Tcb.ProcessThreadListEntry); RemoveEntryList(&current->Tcb.ProcessThreadListEntry);
Last = IsListEmpty(&Process->ThreadListHead); Last = IsListEmpty(&Process->ThreadListHead);
KeReleaseSpinLock(&PiThreadListLock, oldIrql); KeReleaseSpinLock(&PiThreadListLock, oldIrql);
if (Last) if (Last)
@ -113,14 +113,14 @@ PsReapThreads(VOID)
{ {
if (current->Tcb.Teb) if (current->Tcb.Teb)
{ {
/* If this is not the last thread for the process than free the memory /* If this is not the last thread for the process then free the memory
from user stack and teb. */ from user stack and teb. */
NTSTATUS Status; NTSTATUS Status;
ULONG Length; ULONG Length;
ULONG Offset; ULONG Offset;
PVOID DeallocationStack; PVOID DeallocationStack;
HANDLE ProcessHandle; HANDLE ProcessHandle;
Status = ObCreateHandle(PsGetCurrentProcess(), Process, PROCESS_ALL_ACCESS, FALSE, &ProcessHandle); Status = ObCreateHandle(PsGetCurrentProcess(), Process, PROCESS_ALL_ACCESS, FALSE, &ProcessHandle);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("ObCreateHandle failed, status = %x\n", Status); DPRINT1("ObCreateHandle failed, status = %x\n", Status);
@ -128,14 +128,14 @@ PsReapThreads(VOID)
} }
Offset = FIELD_OFFSET(TEB, DeallocationStack); Offset = FIELD_OFFSET(TEB, DeallocationStack);
Length = 0; Length = 0;
NtReadVirtualMemory(ProcessHandle, (PVOID)current->Tcb.Teb + Offset, NtReadVirtualMemory(ProcessHandle, (PVOID)current->Tcb.Teb + Offset,
(PVOID)&DeallocationStack, sizeof(PVOID), &Length); (PVOID)&DeallocationStack, sizeof(PVOID), &Length);
if (DeallocationStack && Length == sizeof(PVOID)) if (DeallocationStack && Length == sizeof(PVOID))
{ {
NtFreeVirtualMemory(ProcessHandle, &DeallocationStack, &Length, MEM_RELEASE); NtFreeVirtualMemory(ProcessHandle, &DeallocationStack, &Length, MEM_RELEASE);
} }
Length = PAGE_SIZE; Length = PAGE_SIZE;
NtFreeVirtualMemory(ProcessHandle, (PVOID*)&current->Tcb.Teb, &Length, MEM_RELEASE); NtFreeVirtualMemory(ProcessHandle, (PVOID*)&current->Tcb.Teb, &Length, MEM_RELEASE);
NtClose(ProcessHandle); NtClose(ProcessHandle);
} }
} }
@ -183,12 +183,12 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus)
current_entry = Thread->MutantListHead.Flink; current_entry = Thread->MutantListHead.Flink;
} }
KeAcquireSpinLock(&PiThreadListLock, &oldIrql); KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
KeAcquireDispatcherDatabaseLock(FALSE); KeAcquireDispatcherDatabaseLockAtDpcLevel();
CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE; CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE;
KeDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader); KeDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader);
KeReleaseDispatcherDatabaseLockAtDpcLevel(FALSE); KeReleaseDispatcherDatabaseLockFromDpcLevel ();
ExpSwapThreadEventPair(CurrentThread, NULL); /* Release the associated eventpair object, if there was one */ ExpSwapThreadEventPair(CurrentThread, NULL); /* Release the associated eventpair object, if there was one */
KeRemoveAllWaitsThread (CurrentThread, STATUS_UNSUCCESSFUL, FALSE); KeRemoveAllWaitsThread (CurrentThread, STATUS_UNSUCCESSFUL, FALSE);
@ -263,6 +263,8 @@ NTSTATUS STDCALL
PiTerminateProcess(PEPROCESS Process, PiTerminateProcess(PEPROCESS Process,
NTSTATUS ExitStatus) NTSTATUS ExitStatus)
{ {
KIRQL OldIrql;
DPRINT("PiTerminateProcess(Process %x, ExitStatus %x) PC %d HC %d\n", DPRINT("PiTerminateProcess(Process %x, ExitStatus %x) PC %d HC %d\n",
Process, ExitStatus, ObGetObjectPointerCount(Process), Process, ExitStatus, ObGetObjectPointerCount(Process),
ObGetObjectHandleCount(Process)); ObGetObjectHandleCount(Process));
@ -278,10 +280,10 @@ PiTerminateProcess(PEPROCESS Process,
KeAttachProcess( Process ); KeAttachProcess( Process );
ObCloseAllHandles(Process); ObCloseAllHandles(Process);
KeDetachProcess(); KeDetachProcess();
KeAcquireDispatcherDatabaseLock(FALSE); OldIrql = KeAcquireDispatcherDatabaseLock ();
Process->Pcb.DispatcherHeader.SignalState = TRUE; Process->Pcb.DispatcherHeader.SignalState = TRUE;
KeDispatcherObjectWake(&Process->Pcb.DispatcherHeader); KeDispatcherObjectWake(&Process->Pcb.DispatcherHeader);
KeReleaseDispatcherDatabaseLock(FALSE); KeReleaseDispatcherDatabaseLock (OldIrql);
ObDereferenceObject(Process); ObDereferenceObject(Process);
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }

View file

@ -1,4 +1,4 @@
/* $Id: thread.c,v 1.120 2003/10/12 17:05:50 hbirr Exp $ /* $Id: thread.c,v 1.121 2003/11/02 01:16:21 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -52,7 +52,7 @@ ULONG PiNrThreads = 0;
ULONG PiNrReadyThreads = 0; ULONG PiNrReadyThreads = 0;
static HANDLE PiReaperThreadHandle; static HANDLE PiReaperThreadHandle;
static KEVENT PiReaperThreadEvent; static KEVENT PiReaperThreadEvent;
static BOOL PiReaperThreadShouldTerminate = FALSE; static BOOLEAN PiReaperThreadShouldTerminate = FALSE;
ULONG PiNrThreadsAwaitingReaping = 0; ULONG PiNrThreadsAwaitingReaping = 0;
static GENERIC_MAPPING PiThreadMapping = {THREAD_READ, static GENERIC_MAPPING PiThreadMapping = {THREAD_READ,
@ -293,7 +293,7 @@ PsDispatchThread(ULONG NewThreadStatus)
/* /*
* Save wait IRQL * Save wait IRQL
*/ */
((PIKPCR) KeGetCurrentKPCR())->CurrentThread->WaitIrql = oldIrql; ((PIKPCR) KeGetCurrentKPCR())->CurrentThread->WaitIrql = oldIrql;
PsDispatchThreadNoLock(NewThreadStatus); PsDispatchThreadNoLock(NewThreadStatus);
KeLowerIrql(oldIrql); KeLowerIrql(oldIrql);
} }
@ -304,16 +304,16 @@ PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus)
KIRQL oldIrql; KIRQL oldIrql;
KeAcquireSpinLock(&PiThreadListLock, &oldIrql); KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
if (THREAD_STATE_TERMINATED_1 == Thread->Tcb.State || if (THREAD_STATE_TERMINATED_1 == Thread->Tcb.State ||
THREAD_STATE_TERMINATED_2 == Thread->Tcb.State) THREAD_STATE_TERMINATED_2 == Thread->Tcb.State)
{ {
DPRINT("Can't unblock thread %d because it's terminating\n", DPRINT("Can't unblock thread %d because it's terminating\n",
Thread->Cid.UniqueThread); Thread->Cid.UniqueThread);
} }
else if (THREAD_STATE_READY == Thread->Tcb.State || else if (THREAD_STATE_READY == Thread->Tcb.State ||
THREAD_STATE_RUNNING == Thread->Tcb.State) THREAD_STATE_RUNNING == Thread->Tcb.State)
{ {
DPRINT("Can't unblock thread %d because it's ready or running\n", DPRINT("Can't unblock thread %d because it's ready or running\n",
Thread->Cid.UniqueThread); Thread->Cid.UniqueThread);
} }
else else
@ -329,7 +329,7 @@ PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus)
} }
VOID VOID
PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode, PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
BOOLEAN DispatcherLock, KIRQL WaitIrql, UCHAR WaitReason) BOOLEAN DispatcherLock, KIRQL WaitIrql, UCHAR WaitReason)
{ {
KIRQL oldIrql; KIRQL oldIrql;
@ -345,7 +345,7 @@ PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
{ {
if (!DispatcherLock) if (!DispatcherLock)
{ {
KeAcquireDispatcherDatabaseLock(FALSE); KeAcquireDispatcherDatabaseLockAtDpcLevel();
} }
WaitBlock = (PKWAIT_BLOCK)Thread->Tcb.WaitBlockList; WaitBlock = (PKWAIT_BLOCK)Thread->Tcb.WaitBlockList;
while (WaitBlock) while (WaitBlock)
@ -354,7 +354,7 @@ PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
WaitBlock = WaitBlock->NextWaitBlock; WaitBlock = WaitBlock->NextWaitBlock;
} }
Thread->Tcb.WaitBlockList = NULL; Thread->Tcb.WaitBlockList = NULL;
KeReleaseDispatcherDatabaseLockAtDpcLevel(FALSE); KeReleaseDispatcherDatabaseLockFromDpcLevel();
PsDispatchThreadNoLock (THREAD_STATE_READY); PsDispatchThreadNoLock (THREAD_STATE_READY);
if (Status != NULL) if (Status != NULL)
{ {
@ -365,7 +365,7 @@ PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode,
{ {
if (DispatcherLock) if (DispatcherLock)
{ {
KeReleaseDispatcherDatabaseLockAtDpcLevel(FALSE); KeReleaseDispatcherDatabaseLockFromDpcLevel();
} }
Thread->Tcb.Alertable = Alertable; Thread->Tcb.Alertable = Alertable;
Thread->Tcb.WaitMode = WaitMode; Thread->Tcb.WaitMode = WaitMode;
@ -618,7 +618,7 @@ KeSetAffinityThread(PKTHREAD Thread,
} }
NTSTATUS STDCALL NTSTATUS STDCALL
NtAlertResumeThread(IN HANDLE ThreadHandle, NtAlertResumeThread(IN HANDLE ThreadHandle,
OUT PULONG SuspendCount) OUT PULONG SuspendCount)
{ {
@ -626,7 +626,8 @@ NtAlertResumeThread(IN HANDLE ThreadHandle,
} }
NTSTATUS STDCALL NtAlertThread (IN HANDLE ThreadHandle) NTSTATUS STDCALL
NtAlertThread (IN HANDLE ThreadHandle)
{ {
PETHREAD Thread; PETHREAD Thread;
NTSTATUS Status; NTSTATUS Status;
@ -655,7 +656,7 @@ NTSTATUS STDCALL NtAlertThread (IN HANDLE ThreadHandle)
* *
* @implemented * @implemented
*/ */
NTSTATUS STDCALL NTSTATUS STDCALL
NtOpenThread(OUT PHANDLE ThreadHandle, NtOpenThread(OUT PHANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess, IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes, IN POBJECT_ATTRIBUTES ObjectAttributes,
@ -711,13 +712,13 @@ NtOpenThread(OUT PHANDLE ThreadHandle,
DesiredAccess, DesiredAccess,
FALSE, FALSE,
ThreadHandle); ThreadHandle);
ObDereferenceObject(EThread); ObDereferenceObject(EThread);
} }
} }
return(Status); return(Status);
} }
NTSTATUS STDCALL NTSTATUS STDCALL
NtContinue(IN PCONTEXT Context, NtContinue(IN PCONTEXT Context,
IN BOOLEAN TestAlert) IN BOOLEAN TestAlert)
{ {