mirror of
https://github.com/reactos/reactos.git
synced 2025-04-27 00:50:23 +00:00
- Add KiCheckThreadStackSwap and KiAddThreadToWaitList macros
- Initialize PRCBs' Wait Lists - Fix a ghastly implementation fault where the the queue code was correctly removing the thread from its wait list, but where this wait list was actually connected to the _SCHEDULER_ and ended up removing a thread behind its back, causing bizarre issues and w3seek's ASSERT(State == Ready) bug. Fixed this by using the macros above and PRCB Wait List and properly inserting a waiting thread into that list, and then removing it when unblocking it or removing a queue. svn path=/trunk/; revision=23056
This commit is contained in:
parent
8d372c2271
commit
1f1857f96d
5 changed files with 64 additions and 4 deletions
|
@ -155,6 +155,40 @@
|
|||
} \
|
||||
}
|
||||
|
||||
//
|
||||
// Determines wether a thread should be added to the wait list
|
||||
//
|
||||
#define KiCheckThreadStackSwap(WaitMode, Thread, Swappable) \
|
||||
{ \
|
||||
/* Check the required conditions */ \
|
||||
if ((WaitMode != KernelMode) && \
|
||||
(Thread->EnableStackSwap) && \
|
||||
(Thread->Priority >= (LOW_REALTIME_PRIORITY + 9))) \
|
||||
{ \
|
||||
/* We are go for swap */ \
|
||||
Swappable = TRUE; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
/* Don't swap the thread */ \
|
||||
Swappable = FALSE; \
|
||||
} \
|
||||
}
|
||||
|
||||
//
|
||||
// Adds a thread to the wait list
|
||||
//
|
||||
#define KiAddThreadToWaitList(Thread, Swappable) \
|
||||
{ \
|
||||
/* Make sure it's swappable */ \
|
||||
if (Swappable) \
|
||||
{ \
|
||||
/* Insert it into the PRCB's List */ \
|
||||
InsertTailList(&KeGetCurrentPrcb()->WaitListHead, \
|
||||
&Thread->WaitListEntry); \
|
||||
} \
|
||||
}
|
||||
|
||||
//
|
||||
// Rules for checking alertability:
|
||||
// - For Alertable waits ONLY:
|
||||
|
|
|
@ -252,6 +252,7 @@ KeApplicationProcessorInit(VOID)
|
|||
KiCheckFPU();
|
||||
|
||||
KeInitDpc(Pcr->Prcb);
|
||||
InitializeListHead(&Pcr->PrcbData.WaitListHead);
|
||||
|
||||
if (Pcr->PrcbData.FeatureBits & X86_FEATURE_SYSCALL)
|
||||
{
|
||||
|
@ -332,6 +333,7 @@ KeInit1(PCHAR CommandLine, PULONG LastKernelAddress)
|
|||
KPCR->NtTib.ExceptionList = (PVOID)-1;
|
||||
|
||||
KeInitDpc(KPCR->Prcb);
|
||||
InitializeListHead(&KPCR->PrcbData.WaitListHead);
|
||||
|
||||
KeInitExceptions ();
|
||||
KeInitInterrupts ();
|
||||
|
|
|
@ -83,7 +83,7 @@ KiScanThreadList(KPRIORITY Priority,
|
|||
|
||||
if (current->State != Ready) {
|
||||
|
||||
DPRINT1("%d/%d\n", ¤t, current->State);
|
||||
DPRINT1("%p/%d\n", current, current->State);
|
||||
}
|
||||
|
||||
ASSERT(current->State == Ready);
|
||||
|
|
|
@ -102,7 +102,7 @@ KiInsertQueue(IN PKQUEUE Queue,
|
|||
|
||||
/* Remove the queue from the thread's wait list */
|
||||
Thread->WaitStatus = (NTSTATUS)Entry;
|
||||
RemoveEntryList(&Thread->WaitListEntry);
|
||||
if (Thread->WaitListEntry.Flink) RemoveEntryList(&Thread->WaitListEntry);
|
||||
Thread->WaitReason = 0;
|
||||
|
||||
/* Increase the active threads and set the status*/
|
||||
|
@ -248,6 +248,7 @@ KeRemoveQueue(IN PKQUEUE Queue,
|
|||
PKQUEUE PreviousQueue;
|
||||
PKWAIT_BLOCK WaitBlock;
|
||||
PKTIMER Timer;
|
||||
BOOLEAN Swappable;
|
||||
ASSERT_QUEUE(Queue);
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
|
||||
|
@ -354,6 +355,10 @@ KeRemoveQueue(IN PKQUEUE Queue,
|
|||
WaitBlock->Thread = Thread;
|
||||
Thread->WaitStatus = STATUS_WAIT_0;
|
||||
|
||||
/* Check if we can swap the thread's stack */
|
||||
Thread->WaitListEntry.Flink = NULL;
|
||||
KiCheckThreadStackSwap(WaitMode, Thread, Swappable);
|
||||
|
||||
/* We need to wait for the object... check for a timeout */
|
||||
if (Timeout)
|
||||
{
|
||||
|
@ -406,6 +411,7 @@ KeRemoveQueue(IN PKQUEUE Queue,
|
|||
Thread->State = Waiting;
|
||||
|
||||
/* Find a new thread to run */
|
||||
KiAddThreadToWaitList(Thread, Swappable);
|
||||
Status = KiSwapThread();
|
||||
|
||||
/* Reset the wait reason */
|
||||
|
|
|
@ -143,8 +143,8 @@ KiAbortWaitThread(IN PKTHREAD Thread,
|
|||
WaitBlock = WaitBlock->NextWaitBlock;
|
||||
} while (WaitBlock != Thread->WaitBlockList);
|
||||
|
||||
/* FIXME: Remove the thread from the wait list! */
|
||||
//RemoveEntryList(&Thread->WaitListEntry);
|
||||
/* Remove the thread from the wait list! */
|
||||
if (Thread->WaitListEntry.Flink) RemoveEntryList(&Thread->WaitListEntry);
|
||||
|
||||
/* Check if there's a Thread Timer */
|
||||
Timer = &Thread->Timer;
|
||||
|
@ -274,6 +274,7 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode,
|
|||
PKTIMER ThreadTimer;
|
||||
PKTHREAD CurrentThread = KeGetCurrentThread();
|
||||
NTSTATUS WaitStatus = STATUS_SUCCESS;
|
||||
BOOLEAN Swappable;
|
||||
|
||||
/* Check if the lock is already held */
|
||||
if (CurrentThread->WaitNext)
|
||||
|
@ -306,6 +307,10 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode,
|
|||
/* Check if we can do an alertable wait, if requested */
|
||||
KiCheckAlertability();
|
||||
|
||||
/* Check if we can swap the thread's stack */
|
||||
CurrentThread->WaitListEntry.Flink = NULL;
|
||||
KiCheckThreadStackSwap(WaitMode, CurrentThread, Swappable);
|
||||
|
||||
/* Set status */
|
||||
CurrentThread->WaitStatus = STATUS_WAIT_0;
|
||||
|
||||
|
@ -341,6 +346,7 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode,
|
|||
CurrentThread->State = Waiting;
|
||||
|
||||
/* Find a new thread to run */
|
||||
KiAddThreadToWaitList(CurrentThread, Swappable);
|
||||
WaitStatus = KiSwapThread();
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
|
||||
|
@ -383,6 +389,7 @@ KeWaitForSingleObject(PVOID Object,
|
|||
PKTIMER ThreadTimer;
|
||||
PKTHREAD CurrentThread = KeGetCurrentThread();
|
||||
NTSTATUS WaitStatus = STATUS_SUCCESS;
|
||||
BOOLEAN Swappable;
|
||||
|
||||
/* Check if the lock is already held */
|
||||
if (CurrentThread->WaitNext)
|
||||
|
@ -461,6 +468,10 @@ KeWaitForSingleObject(PVOID Object,
|
|||
/* Make sure we can satisfy the Alertable request */
|
||||
KiCheckAlertability();
|
||||
|
||||
/* Check if we can swap the thread's stack */
|
||||
CurrentThread->WaitListEntry.Flink = NULL;
|
||||
KiCheckThreadStackSwap(WaitMode, CurrentThread, Swappable);
|
||||
|
||||
/* Enable the Timeout Timer if there was any specified */
|
||||
if (Timeout)
|
||||
{
|
||||
|
@ -512,6 +523,7 @@ KeWaitForSingleObject(PVOID Object,
|
|||
CurrentThread->State = Waiting;
|
||||
|
||||
/* Find a new thread to run */
|
||||
KiAddThreadToWaitList(CurrentThread, Swappable);
|
||||
WaitStatus = KiSwapThread();
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
|
||||
|
@ -564,6 +576,7 @@ KeWaitForMultipleObjects(IN ULONG Count,
|
|||
ULONG AllObjectsSignaled;
|
||||
ULONG WaitIndex;
|
||||
NTSTATUS WaitStatus = STATUS_SUCCESS;
|
||||
BOOLEAN Swappable;
|
||||
|
||||
/* Set the Current Thread */
|
||||
CurrentThread = KeGetCurrentThread();
|
||||
|
@ -727,6 +740,10 @@ KeWaitForMultipleObjects(IN ULONG Count,
|
|||
/* Make sure we can satisfy the Alertable request */
|
||||
KiCheckAlertability();
|
||||
|
||||
/* Check if we can swap the thread's stack */
|
||||
CurrentThread->WaitListEntry.Flink = NULL;
|
||||
KiCheckThreadStackSwap(WaitMode, CurrentThread, Swappable);
|
||||
|
||||
/* Enable the Timeout Timer if there was any specified */
|
||||
if (Timeout)
|
||||
{
|
||||
|
@ -786,6 +803,7 @@ KeWaitForMultipleObjects(IN ULONG Count,
|
|||
CurrentThread->State = Waiting;
|
||||
|
||||
/* Find a new thread to run */
|
||||
KiAddThreadToWaitList(CurrentThread, Swappable);
|
||||
WaitStatus = KiSwapThread();
|
||||
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
|
||||
|
||||
|
|
Loading…
Reference in a new issue