mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
fix kernel queues + misc fixes/cleanups
svn path=/trunk/; revision=11754
This commit is contained in:
parent
0f6f4de9e1
commit
0c5a9ba4f5
8 changed files with 222 additions and 136 deletions
|
@ -124,7 +124,7 @@ KeInsertQueueApc (PKAPC Apc,
|
|||
PLIST_ENTRY ApcListEntry;
|
||||
PKAPC QueuedApc;
|
||||
|
||||
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
DPRINT ("KeInsertQueueApc(Apc %x, SystemArgument1 %x, "
|
||||
"SystemArgument2 %x)\n",Apc,SystemArgument1,
|
||||
SystemArgument2);
|
||||
|
@ -134,7 +134,9 @@ KeInsertQueueApc (PKAPC Apc,
|
|||
/* Get the Thread specified in the APC */
|
||||
Thread = Apc->Thread;
|
||||
|
||||
/* Make sure the thread allows APC Queues */
|
||||
/* Make sure the thread allows APC Queues.
|
||||
* The thread is not apc queueable, for instance, when it's (about to be) terminated.
|
||||
*/
|
||||
if (Thread->ApcQueueable == FALSE) {
|
||||
DPRINT("Thread doesn't allow APC Queues\n");
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
|
@ -194,18 +196,20 @@ KeInsertQueueApc (PKAPC Apc,
|
|||
/* FIXME: Use IPI */
|
||||
DPRINT ("Requesting APC Interrupt for Running Thread \n");
|
||||
HalRequestSoftwareInterrupt(APC_LEVEL);
|
||||
} else if ((Thread->WaitIrql < APC_LEVEL) && (Apc->NormalRoutine == NULL)) {
|
||||
} else if ((Thread->State == THREAD_STATE_BLOCKED) &&
|
||||
(Thread->WaitIrql < APC_LEVEL) &&
|
||||
(Apc->NormalRoutine == NULL))
|
||||
{
|
||||
DPRINT ("Waking up Thread for Kernel-Mode APC Delivery \n");
|
||||
KeRemoveAllWaitsThread(CONTAINING_RECORD(Thread, ETHREAD, Tcb),
|
||||
STATUS_KERNEL_APC,
|
||||
TRUE);
|
||||
KiAbortWaitThread(Thread, STATUS_KERNEL_APC);
|
||||
}
|
||||
} else if ((Thread->WaitMode == UserMode) && (Thread->Alertable)) {
|
||||
} else if ((Thread->State == THREAD_STATE_BLOCKED) &&
|
||||
(Thread->WaitMode == UserMode) &&
|
||||
(Thread->Alertable))
|
||||
{
|
||||
DPRINT ("Waking up Thread for User-Mode APC Delivery \n");
|
||||
Thread->ApcState.UserApcPending = TRUE;
|
||||
KeRemoveAllWaitsThread(CONTAINING_RECORD(Thread, ETHREAD, Tcb),
|
||||
STATUS_USER_APC,
|
||||
TRUE);
|
||||
KiAbortWaitThread(Thread, STATUS_USER_APC);
|
||||
}
|
||||
|
||||
/* Return Sucess if we are here */
|
||||
|
@ -227,7 +231,7 @@ KeRemoveQueueApc (PKAPC Apc)
|
|||
KIRQL OldIrql;
|
||||
PKTHREAD Thread = Apc->Thread;
|
||||
|
||||
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
DPRINT("KeRemoveQueueApc called for APC: %x \n", Apc);
|
||||
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
|
@ -270,7 +274,7 @@ KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
|
|||
PKTHREAD Thread = KeGetCurrentThread();
|
||||
BOOLEAN OldState;
|
||||
|
||||
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
KiAcquireSpinLock(&Thread->ApcQueueLock);
|
||||
|
@ -295,7 +299,7 @@ KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
|
|||
*/
|
||||
VOID
|
||||
STDCALL
|
||||
KiDeliverApc(KPROCESSOR_MODE PreviousMode,
|
||||
KiDeliverApc(KPROCESSOR_MODE DeliveryMode,
|
||||
PVOID Reserved,
|
||||
PKTRAP_FRAME TrapFrame)
|
||||
/*
|
||||
|
@ -318,6 +322,8 @@ KiDeliverApc(KPROCESSOR_MODE PreviousMode,
|
|||
PVOID SystemArgument1;
|
||||
PVOID SystemArgument2;
|
||||
|
||||
ASSERT_IRQL_EQUAL(APC_LEVEL);
|
||||
|
||||
/* Lock the APC Queue and Raise IRQL to Synch */
|
||||
KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
|
||||
|
||||
|
@ -360,6 +366,15 @@ KiDeliverApc(KPROCESSOR_MODE PreviousMode,
|
|||
} else {
|
||||
/* Normal Kernel APC */
|
||||
if (Thread->ApcState.KernelApcInProgress || Thread->KernelApcDisable) {
|
||||
|
||||
/*
|
||||
* DeliveryMode must be KernelMode in this case, since one may not
|
||||
* return to umode while being inside a critical section or while
|
||||
* a regular kmode apc is running (the latter should be impossible btw).
|
||||
* -Gunnar
|
||||
*/
|
||||
ASSERT(DeliveryMode == KernelMode);
|
||||
|
||||
KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
|
||||
return;
|
||||
}
|
||||
|
@ -399,7 +414,7 @@ KiDeliverApc(KPROCESSOR_MODE PreviousMode,
|
|||
|
||||
/* Now we do the User APCs */
|
||||
if ((!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])) &&
|
||||
(PreviousMode == UserMode) &&
|
||||
(DeliveryMode == UserMode) &&
|
||||
(Thread->ApcState.UserApcPending == TRUE)) {
|
||||
|
||||
/* It's not pending anymore */
|
||||
|
@ -418,6 +433,8 @@ KiDeliverApc(KPROCESSOR_MODE PreviousMode,
|
|||
|
||||
/* Remove the APC from Queue, restore IRQL and call the APC */
|
||||
RemoveEntryList(ApcListEntry);
|
||||
Apc->Inserted = FALSE;
|
||||
|
||||
KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
|
||||
DPRINT("Calling the Kernel Routine for for a User APC: %x\n", Apc);
|
||||
KernelRoutine(Apc,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: critical.c,v 1.10 2004/08/15 16:39:05 chorns Exp $
|
||||
/* $Id: critical.c,v 1.11 2004/11/21 18:33:54 gdalsnes Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -22,8 +22,13 @@
|
|||
*/
|
||||
VOID STDCALL KeEnterCriticalRegion (VOID)
|
||||
{
|
||||
PKTHREAD Thread = KeGetCurrentThread();
|
||||
|
||||
DPRINT("KeEnterCriticalRegion()\n");
|
||||
KeGetCurrentThread()->KernelApcDisable--;
|
||||
|
||||
if (!Thread) return; /* <-Early in the boot process the current thread is obseved to be NULL */
|
||||
|
||||
Thread->KernelApcDisable--;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -35,6 +40,8 @@ VOID STDCALL KeLeaveCriticalRegion (VOID)
|
|||
|
||||
DPRINT("KeLeaveCriticalRegion()\n");
|
||||
|
||||
if (!Thread) return; /* <-Early in the boot process the current thread is obseved to be NULL */
|
||||
|
||||
/* Reference: http://www.ntfsd.org/archive/ntfsd0104/msg0203.html */
|
||||
if(++Thread->KernelApcDisable == 0)
|
||||
{
|
||||
|
|
|
@ -67,6 +67,9 @@ LONG STDCALL KeReadStateEvent (PKEVENT Event)
|
|||
*/
|
||||
LONG STDCALL KeResetEvent (PKEVENT Event)
|
||||
{
|
||||
/* FIXME: must use interlocked func. everywhere! (wait.c)
|
||||
* or use dispather lock instead
|
||||
* -Gunnar */
|
||||
return(InterlockedExchange(&(Event->Header.SignalState),0));
|
||||
}
|
||||
|
||||
|
@ -86,7 +89,7 @@ LONG STDCALL KeSetEvent (PKEVENT Event,
|
|||
|
||||
ret = InterlockedExchange(&(Event->Header.SignalState),1);
|
||||
|
||||
KeDispatcherObjectWake((DISPATCHER_HEADER *)Event);
|
||||
KiDispatcherObjectWake((DISPATCHER_HEADER *)Event);
|
||||
|
||||
if (Wait == FALSE)
|
||||
{
|
||||
|
@ -115,7 +118,7 @@ NTSTATUS STDCALL KePulseEvent (PKEVENT Event,
|
|||
DPRINT("KePulseEvent(Event %x, Wait %x)\n",Event,Wait);
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
ret = InterlockedExchange(&(Event->Header.SignalState),1);
|
||||
KeDispatcherObjectWake((DISPATCHER_HEADER *)Event);
|
||||
KiDispatcherObjectWake((DISPATCHER_HEADER *)Event);
|
||||
InterlockedExchange(&(Event->Header.SignalState),0);
|
||||
|
||||
if (Wait == FALSE)
|
||||
|
@ -143,6 +146,9 @@ KeSetEventBoostPriority(
|
|||
)
|
||||
{
|
||||
PKTHREAD WaitingThread;
|
||||
KIRQL OldIrql;
|
||||
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
|
||||
/* Get Thread that is currently waiting. First get the Wait Block, then the Thread */
|
||||
WaitingThread = CONTAINING_RECORD(Event->Header.WaitListHead.Flink, KWAIT_BLOCK, WaitListEntry)->Thread;
|
||||
|
@ -152,7 +158,9 @@ KeSetEventBoostPriority(
|
|||
|
||||
/* Reset the Quantum and Unwait the Thread */
|
||||
WaitingThread->Quantum = WaitingThread->ApcState.Process->ThreadQuantum;
|
||||
KeRemoveAllWaitsThread((PETHREAD)WaitingThread, STATUS_SUCCESS, TRUE);
|
||||
KiAbortWaitThread(WaitingThread, STATUS_SUCCESS);
|
||||
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -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.18 2004/10/22 20:30:48 ekohl Exp $
|
||||
/* $Id: mutex.c,v 1.19 2004/11/21 18:33:54 gdalsnes Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/mutex.c
|
||||
|
@ -82,7 +82,7 @@ KeReleaseMutex(IN PKMUTEX Mutex,
|
|||
Mutex->OwnerThread = NULL;
|
||||
if (Mutex->MutantListEntry.Flink && Mutex->MutantListEntry.Blink)
|
||||
RemoveEntryList(&Mutex->MutantListEntry);
|
||||
KeDispatcherObjectWake(&Mutex->Header);
|
||||
KiDispatcherObjectWake(&Mutex->Header);
|
||||
}
|
||||
|
||||
if (Wait == FALSE)
|
||||
|
@ -191,7 +191,7 @@ KeReleaseMutant(IN PKMUTANT Mutant,
|
|||
Mutant->OwnerThread = NULL;
|
||||
if (Mutant->MutantListEntry.Flink && Mutant->MutantListEntry.Blink)
|
||||
RemoveEntryList(&Mutant->MutantListEntry);
|
||||
KeDispatcherObjectWake(&Mutant->Header);
|
||||
KiDispatcherObjectWake(&Mutant->Header);
|
||||
}
|
||||
|
||||
if (Wait == FALSE)
|
||||
|
|
|
@ -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: queue.c,v 1.11 2004/08/15 16:39:05 chorns Exp $
|
||||
/* $Id: queue.c,v 1.12 2004/11/21 18:33:54 gdalsnes Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/queue.c
|
||||
|
@ -34,6 +34,7 @@
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
@ -54,6 +55,8 @@ KeInitializeQueue(IN PKQUEUE Queue,
|
|||
|
||||
/*
|
||||
* @implemented
|
||||
*
|
||||
* Returns number of entries in the queue
|
||||
*/
|
||||
LONG STDCALL
|
||||
KeReadStateQueue(IN PKQUEUE Queue)
|
||||
|
@ -61,7 +64,9 @@ KeReadStateQueue(IN PKQUEUE Queue)
|
|||
return(Queue->Header.SignalState);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns the previous number of entries in the queue
|
||||
*/
|
||||
LONG STDCALL
|
||||
KiInsertQueue(
|
||||
IN PKQUEUE Queue,
|
||||
|
@ -70,14 +75,10 @@ KiInsertQueue(
|
|||
)
|
||||
{
|
||||
ULONG InitialState;
|
||||
KIRQL OldIrql;
|
||||
|
||||
DPRINT("KiInsertQueue(Queue %x, Entry %x)\n", Queue, Entry);
|
||||
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||
|
||||
InitialState = Queue->Header.SignalState;
|
||||
Queue->Header.SignalState++;
|
||||
|
||||
if (Head)
|
||||
{
|
||||
|
@ -88,12 +89,20 @@ KiInsertQueue(
|
|||
InsertTailList(&Queue->EntryListHead, Entry);
|
||||
}
|
||||
|
||||
if (Queue->CurrentCount < Queue->MaximumCount && InitialState == 0)
|
||||
//inc. num entries in queue
|
||||
Queue->Header.SignalState++;
|
||||
|
||||
/* Why the KeGetCurrentThread()->Queue != Queue?
|
||||
* KiInsertQueue might be called from an APC for the current thread.
|
||||
* -Gunnar
|
||||
*/
|
||||
if (Queue->CurrentCount < Queue->MaximumCount &&
|
||||
!IsListEmpty(&Queue->Header.WaitListHead) &&
|
||||
KeGetCurrentThread()->Queue != Queue)
|
||||
{
|
||||
KeDispatcherObjectWake(&Queue->Header);
|
||||
KiDispatcherObjectWake(&Queue->Header);
|
||||
}
|
||||
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
return InitialState;
|
||||
}
|
||||
|
||||
|
@ -106,7 +115,14 @@ LONG STDCALL
|
|||
KeInsertHeadQueue(IN PKQUEUE Queue,
|
||||
IN PLIST_ENTRY Entry)
|
||||
{
|
||||
return KiInsertQueue(Queue,Entry,TRUE);
|
||||
LONG Result;
|
||||
KIRQL OldIrql;
|
||||
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
Result = KiInsertQueue(Queue,Entry,TRUE);
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -117,7 +133,14 @@ LONG STDCALL
|
|||
KeInsertQueue(IN PKQUEUE Queue,
|
||||
IN PLIST_ENTRY Entry)
|
||||
{
|
||||
return KiInsertQueue(Queue,Entry,FALSE);
|
||||
LONG Result;
|
||||
KIRQL OldIrql;
|
||||
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock();
|
||||
Result = KiInsertQueue(Queue,Entry,FALSE);
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -129,6 +152,7 @@ KeRemoveQueue(IN PKQUEUE Queue,
|
|||
IN KPROCESSOR_MODE WaitMode,
|
||||
IN PLARGE_INTEGER Timeout OPTIONAL)
|
||||
{
|
||||
|
||||
PLIST_ENTRY ListEntry;
|
||||
NTSTATUS Status;
|
||||
PKTHREAD Thread = KeGetCurrentThread();
|
||||
|
@ -136,50 +160,75 @@ KeRemoveQueue(IN PKQUEUE Queue,
|
|||
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||
|
||||
//assiciate new thread with queue?
|
||||
if (Thread->Queue != Queue)
|
||||
{
|
||||
//remove association from other queue
|
||||
if (!IsListEmpty(&Thread->QueueListEntry))
|
||||
/*
|
||||
* INVESTIGATE: What is the Thread->QueueListEntry used for? It's linked it into the
|
||||
* Queue->ThreadListHead when the thread registers with the queue and unlinked when
|
||||
* the thread registers with a new queue. The Thread->Queue already tells us what
|
||||
* queue the thread is registered with.
|
||||
* -Gunnar
|
||||
*/
|
||||
|
||||
//unregister thread from previous queue (if any)
|
||||
if (Thread->Queue)
|
||||
{
|
||||
RemoveEntryList(&Thread->QueueListEntry);
|
||||
Thread->Queue->CurrentCount--;
|
||||
|
||||
if (Thread->Queue->CurrentCount < Thread->Queue->MaximumCount &&
|
||||
!IsListEmpty(&Thread->Queue->EntryListHead))
|
||||
{
|
||||
KiDispatcherObjectWake(&Thread->Queue->Header);
|
||||
}
|
||||
}
|
||||
|
||||
//associate with this queue
|
||||
InsertHeadList(&Queue->ThreadListHead, &Thread->QueueListEntry);
|
||||
Queue->CurrentCount++;
|
||||
// register thread with this queue
|
||||
InsertTailList(&Queue->ThreadListHead, &Thread->QueueListEntry);
|
||||
Thread->Queue = Queue;
|
||||
}
|
||||
|
||||
if (Queue->CurrentCount <= Queue->MaximumCount && !IsListEmpty(&Queue->EntryListHead))
|
||||
else /* if (Thread->Queue == Queue) */
|
||||
{
|
||||
ListEntry = RemoveHeadList(&Queue->EntryListHead);
|
||||
Queue->Header.SignalState--;
|
||||
KeReleaseDispatcherDatabaseLock (OldIrql);
|
||||
return ListEntry;
|
||||
//dec. num running threads
|
||||
Queue->CurrentCount--;
|
||||
}
|
||||
|
||||
//need to wait for it...
|
||||
KeReleaseDispatcherDatabaseLock (OldIrql);
|
||||
|
||||
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (Queue->CurrentCount < Queue->MaximumCount && !IsListEmpty(&Queue->EntryListHead))
|
||||
{
|
||||
ListEntry = RemoveHeadList(&Queue->EntryListHead);
|
||||
//dec. num entries in queue
|
||||
Queue->Header.SignalState--;
|
||||
//inc. num running threads
|
||||
Queue->CurrentCount++;
|
||||
|
||||
KeReleaseDispatcherDatabaseLock(OldIrql);
|
||||
return ListEntry;
|
||||
}
|
||||
else
|
||||
{
|
||||
//inform KeWaitXxx that we are holding disp. lock
|
||||
Thread->WaitNext = TRUE;
|
||||
Thread->WaitIrql = OldIrql;
|
||||
|
||||
Status = KeWaitForSingleObject(Queue,
|
||||
WrQueue,
|
||||
WaitMode,
|
||||
TRUE,//Alertable,
|
||||
TRUE, //bAlertable
|
||||
Timeout);
|
||||
|
||||
if (Status == STATUS_TIMEOUT || Status == STATUS_USER_APC)
|
||||
{
|
||||
return (PVOID)Status;
|
||||
}
|
||||
else
|
||||
{
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||
ListEntry = RemoveHeadList(&Queue->EntryListHead);
|
||||
KeReleaseDispatcherDatabaseLock (OldIrql);
|
||||
return ListEntry;
|
||||
}
|
||||
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -195,23 +244,31 @@ KeRundownQueue(IN PKQUEUE Queue)
|
|||
|
||||
DPRINT("KeRundownQueue(Queue %x)\n", Queue);
|
||||
|
||||
//FIXME: should we wake thread waiting on a queue?
|
||||
/* I'm just guessing how this should work:-/
|
||||
* -Gunnar
|
||||
*/
|
||||
|
||||
OldIrql = KeAcquireDispatcherDatabaseLock ();
|
||||
|
||||
// Clear Queue and QueueListEntry members of all threads associated with this queue
|
||||
//no thread must wait on queue at rundown
|
||||
ASSERT(IsListEmpty(&Queue->Header.WaitListHead));
|
||||
|
||||
// unlink threads and clear their Thread->Queue
|
||||
while (!IsListEmpty(&Queue->ThreadListHead))
|
||||
{
|
||||
EnumEntry = RemoveHeadList(&Queue->ThreadListHead);
|
||||
InitializeListHead(EnumEntry);
|
||||
Thread = CONTAINING_RECORD(EnumEntry, KTHREAD, QueueListEntry);
|
||||
Thread->Queue = NULL;
|
||||
}
|
||||
|
||||
if (!IsListEmpty(&Queue->EntryListHead))
|
||||
EnumEntry = Queue->EntryListHead.Flink;
|
||||
else
|
||||
if (IsListEmpty(&Queue->EntryListHead))
|
||||
{
|
||||
EnumEntry = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
EnumEntry = Queue->EntryListHead.Flink;
|
||||
}
|
||||
|
||||
KeReleaseDispatcherDatabaseLock (OldIrql);
|
||||
|
||||
|
|
|
@ -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.15 2004/08/15 16:39:05 chorns Exp $
|
||||
/* $Id: sem.c,v 1.16 2004/11/21 18:33:54 gdalsnes Exp $
|
||||
*
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ke/sem.c
|
||||
|
@ -105,7 +105,7 @@ KeReleaseSemaphore (PKSEMAPHORE Semaphore,
|
|||
Semaphore->Header.SignalState += Adjustment;
|
||||
if (InitialState == 0)
|
||||
{
|
||||
KeDispatcherObjectWake(&Semaphore->Header);
|
||||
KiDispatcherObjectWake(&Semaphore->Header);
|
||||
}
|
||||
|
||||
if (Wait == FALSE)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: timer.c,v 1.89 2004/11/21 06:51:18 ion Exp $
|
||||
/* $Id: timer.c,v 1.90 2004/11/21 18:33:54 gdalsnes Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -526,11 +526,11 @@ HandleExpiredTimer(PKTIMER Timer)
|
|||
DPRINT("Finished dpc routine\n");
|
||||
}
|
||||
|
||||
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
||||
ASSERT_IRQL_EQUAL(DISPATCH_LEVEL);
|
||||
|
||||
KeAcquireDispatcherDatabaseLockAtDpcLevel();
|
||||
Timer->Header.SignalState = TRUE;
|
||||
KeDispatcherObjectWake(&Timer->Header);
|
||||
KiDispatcherObjectWake(&Timer->Header);
|
||||
KeReleaseDispatcherDatabaseLockFromDpcLevel();
|
||||
|
||||
if (Timer->Period != 0)
|
||||
|
@ -571,7 +571,7 @@ KeExpireTimers(PKDPC Dpc,
|
|||
|
||||
DPRINT("KeExpireTimers()\n");
|
||||
|
||||
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
||||
ASSERT_IRQL_EQUAL(DISPATCH_LEVEL);
|
||||
|
||||
InitializeListHead(&TimerList);
|
||||
|
||||
|
|
|
@ -110,6 +110,8 @@ KiSideEffectsBeforeWake(DISPATCHER_HEADER * hdr,
|
|||
break;
|
||||
|
||||
case InternalQueueType:
|
||||
break;
|
||||
|
||||
case InternalSemaphoreType:
|
||||
hdr->SignalState--;
|
||||
break;
|
||||
|
@ -193,33 +195,31 @@ KiIsObjectSignalled(DISPATCHER_HEADER * hdr,
|
|||
}
|
||||
}
|
||||
|
||||
VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus, BOOL Unblock)
|
||||
/* Must be called with the dispatcher lock held */
|
||||
BOOLEAN KiAbortWaitThread(PKTHREAD Thread, NTSTATUS WaitStatus)
|
||||
{
|
||||
PKWAIT_BLOCK WaitBlock, PrevWaitBlock;
|
||||
BOOLEAN WasWaiting = FALSE;
|
||||
PKWAIT_BLOCK WaitBlock;
|
||||
BOOLEAN WasWaiting;
|
||||
|
||||
WaitBlock = (PKWAIT_BLOCK)Thread->Tcb.WaitBlockList;
|
||||
if (WaitBlock != NULL)
|
||||
/* if we are blocked, we must be waiting on something also */
|
||||
ASSERT((Thread->State == THREAD_STATE_BLOCKED) == (Thread->WaitBlockList != NULL));
|
||||
|
||||
WaitBlock = (PKWAIT_BLOCK)Thread->WaitBlockList;
|
||||
WasWaiting = (WaitBlock != NULL);
|
||||
|
||||
while (WaitBlock)
|
||||
{
|
||||
WasWaiting = TRUE;
|
||||
}
|
||||
while (WaitBlock != NULL)
|
||||
{
|
||||
if (WaitBlock->WaitListEntry.Flink != NULL && WaitBlock->WaitListEntry.Blink != NULL)
|
||||
{
|
||||
RemoveEntryList (&WaitBlock->WaitListEntry);
|
||||
WaitBlock->WaitListEntry.Flink = WaitBlock->WaitListEntry.Blink = NULL;
|
||||
}
|
||||
PrevWaitBlock = WaitBlock;
|
||||
RemoveEntryList(&WaitBlock->WaitListEntry);
|
||||
WaitBlock = WaitBlock->NextWaitBlock;
|
||||
PrevWaitBlock->NextWaitBlock = NULL;
|
||||
}
|
||||
Thread->Tcb.WaitBlockList = NULL;
|
||||
|
||||
if (WasWaiting && Unblock)
|
||||
Thread->WaitBlockList = NULL;
|
||||
|
||||
if (WasWaiting)
|
||||
{
|
||||
PsUnblockThread(Thread, &WaitStatus);
|
||||
PsUnblockThread((PETHREAD)Thread, &WaitStatus);
|
||||
}
|
||||
return WasWaiting;
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
|
@ -259,12 +259,8 @@ KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr,
|
|||
{
|
||||
DPRINT("WaitAny: Remove all wait blocks.\n");
|
||||
for (Waiter = WaiterHead->Thread->WaitBlockList; Waiter; Waiter = Waiter->NextWaitBlock)
|
||||
{
|
||||
if (Waiter->WaitListEntry.Flink != NULL && Waiter->WaitListEntry.Blink != NULL)
|
||||
{
|
||||
RemoveEntryList(&Waiter->WaitListEntry);
|
||||
Waiter->WaitListEntry.Flink = Waiter->WaitListEntry.Blink = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
WaiterHead->Thread->WaitBlockList = NULL;
|
||||
|
@ -273,7 +269,7 @@ KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr,
|
|||
* If a WakeAll KiSideEffectsBeforeWake(hdr,.. will be called several times,
|
||||
* but thats ok since WakeAll objects has no sideeffects.
|
||||
*/
|
||||
Abandoned = KiSideEffectsBeforeWake(hdr, WaiterHead->Thread) ? TRUE : Abandoned;
|
||||
Abandoned |= KiSideEffectsBeforeWake(hdr, WaiterHead->Thread);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -298,17 +294,12 @@ KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr,
|
|||
if (AllSignaled)
|
||||
{
|
||||
for (Waiter = WaiterHead->Thread->WaitBlockList; Waiter; Waiter = Waiter->NextWaitBlock)
|
||||
{
|
||||
if (Waiter->WaitListEntry.Flink != NULL && Waiter->WaitListEntry.Blink != NULL)
|
||||
{
|
||||
RemoveEntryList(&Waiter->WaitListEntry);
|
||||
Waiter->WaitListEntry.Flink = Waiter->WaitListEntry.Blink = NULL;
|
||||
}
|
||||
|
||||
if (Waiter->WaitType == WaitAll)
|
||||
{
|
||||
Abandoned = KiSideEffectsBeforeWake(Waiter->Object, Waiter->Thread)
|
||||
? TRUE : Abandoned;
|
||||
Abandoned |= KiSideEffectsBeforeWake(Waiter->Object, Waiter->Thread);
|
||||
}
|
||||
|
||||
//no WaitAny objects can possibly be signaled since we are here
|
||||
|
@ -339,7 +330,7 @@ KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr,
|
|||
}
|
||||
|
||||
|
||||
BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr)
|
||||
BOOLEAN KiDispatcherObjectWake(DISPATCHER_HEADER* hdr)
|
||||
/*
|
||||
* FUNCTION: Wake threads waiting on a dispatcher object
|
||||
* NOTE: The exact semantics of waking are dependant on the type of object
|
||||
|
@ -366,6 +357,8 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr)
|
|||
return(KeDispatcherObjectWakeOne(hdr));
|
||||
|
||||
case InternalQueueType:
|
||||
return(KeDispatcherObjectWakeOne(hdr));
|
||||
|
||||
case InternalSemaphoreType:
|
||||
DPRINT("hdr->SignalState %d\n", hdr->SignalState);
|
||||
if(hdr->SignalState>0)
|
||||
|
@ -483,7 +476,6 @@ KeWaitForMultipleObjects(ULONG Count,
|
|||
ULONG CountSignaled;
|
||||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
KIRQL WaitIrql;
|
||||
KIRQL OldIrql;
|
||||
BOOLEAN Abandoned;
|
||||
|
||||
|
@ -493,7 +485,6 @@ KeWaitForMultipleObjects(ULONG Count,
|
|||
ASSERT(0 < Count && Count <= EX_MAXIMUM_WAIT_OBJECTS);
|
||||
|
||||
CurrentThread = KeGetCurrentThread();
|
||||
WaitIrql = KeGetCurrentIrql();
|
||||
|
||||
/*
|
||||
* Work out where we are going to put the wait blocks
|
||||
|
@ -516,6 +507,8 @@ KeWaitForMultipleObjects(ULONG Count,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Set up the timeout if required
|
||||
*/
|
||||
|
@ -528,9 +521,8 @@ KeWaitForMultipleObjects(ULONG Count,
|
|||
{
|
||||
if (CurrentThread->WaitNext)
|
||||
{
|
||||
CurrentThread->WaitNext = FALSE;
|
||||
OldIrql = CurrentThread->WaitIrql;
|
||||
CurrentThread->WaitNext = 0;
|
||||
CurrentThread->WaitIrql = PASSIVE_LEVEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -711,28 +703,33 @@ KeWaitForMultipleObjects(ULONG Count,
|
|||
&CurrentThread->WaitBlock[3].WaitListEntry);
|
||||
}
|
||||
|
||||
//io completion
|
||||
if (CurrentThread->Queue)
|
||||
//kernel queues
|
||||
if (CurrentThread->Queue && WaitReason != WrQueue)
|
||||
{
|
||||
DPRINT("queue: sleep on something else\n");
|
||||
CurrentThread->Queue->CurrentCount--;
|
||||
if (WaitReason != WrQueue && CurrentThread->Queue->CurrentCount < CurrentThread->Queue->MaximumCount &&
|
||||
|
||||
//wake another thread
|
||||
if (CurrentThread->Queue->CurrentCount < CurrentThread->Queue->MaximumCount &&
|
||||
!IsListEmpty(&CurrentThread->Queue->EntryListHead))
|
||||
{
|
||||
KeDispatcherObjectWake(&CurrentThread->Queue->Header);
|
||||
KiDispatcherObjectWake(&CurrentThread->Queue->Header);
|
||||
}
|
||||
}
|
||||
|
||||
PsBlockThread(&Status, Alertable, WaitMode, TRUE, WaitIrql, (UCHAR)WaitReason);
|
||||
PsBlockThread(&Status, Alertable, WaitMode, TRUE, OldIrql, (UCHAR)WaitReason);
|
||||
|
||||
//io completion
|
||||
if (CurrentThread->Queue)
|
||||
//kernel queues
|
||||
//FIXME: dispatcher lock not held here!
|
||||
if (CurrentThread->Queue && WaitReason != WrQueue)
|
||||
{
|
||||
DPRINT("queue: wake from something else\n");
|
||||
CurrentThread->Queue->CurrentCount++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
while (Status == STATUS_KERNEL_APC);
|
||||
} while (Status == STATUS_KERNEL_APC);
|
||||
|
||||
|
||||
if (Timeout != NULL)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue