- Remove all wait objects from a thread which would be deleted.

- Release the thread list lock after the real context switch
  (some code was moved from thread.c to tskswitch.S).
- Check for the state of a thread which is blocked or unblocked,
  because it is possible that there was a second thread switching.
- Fixed KeSetBasePriorityThread.
- Check for a necessary task switch after changing the thread priority in KeSetPriorityThread.

svn path=/trunk/; revision=5642
This commit is contained in:
Hartmut Birr 2003-08-18 11:23:32 +00:00
parent 7aab7f108b
commit 14aa056fe0
5 changed files with 44 additions and 17 deletions

View file

@ -50,7 +50,7 @@ VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header, ULONG Type,
ULONG Size, ULONG SignalState);
VOID KeDumpStackFrames(PULONG Frame);
BOOLEAN KiTestAlert(VOID);
VOID KeRemoveAllWaitsThread(struct _ETHREAD* Thread, NTSTATUS WaitStatus);
VOID KeRemoveAllWaitsThread(struct _ETHREAD* Thread, NTSTATUS WaitStatus, BOOL Unblock);
PULONG KeGetStackTopThread(struct _ETHREAD* Thread);
VOID KeContextToTrapFrame(PCONTEXT Context,
PKTRAP_FRAME TrapFrame);

View file

@ -373,7 +373,7 @@ KeInsertQueueApc (PKAPC Apc,
Apc->NormalRoutine == NULL)
{
KeRemoveAllWaitsThread(CONTAINING_RECORD(TargetThread, ETHREAD, Tcb),
STATUS_KERNEL_APC);
STATUS_KERNEL_APC, TRUE);
}
/*
@ -390,7 +390,7 @@ KeInsertQueueApc (PKAPC Apc,
PETHREAD Thread;
Thread = CONTAINING_RECORD(TargetThread, ETHREAD, Tcb);
KeRemoveAllWaitsThread(Thread, STATUS_USER_APC);
KeRemoveAllWaitsThread(Thread, STATUS_USER_APC, TRUE);
}
}
@ -409,7 +409,7 @@ KeInsertQueueApc (PKAPC Apc,
Status = STATUS_USER_APC;
TargetThread->Alerted[0] = 1;
KeRemoveAllWaitsThread(CONTAINING_RECORD(TargetThread, ETHREAD, Tcb),
STATUS_USER_APC);
STATUS_USER_APC, TRUE);
}
KeReleaseSpinLock(&PiApcLock, oldlvl);
return TRUE;

View file

@ -144,6 +144,14 @@ _Ki386ContextSwitch:
*/
sti
push $_PiThreadListLock
call _KeReleaseSpinLockFromDpcLevel@4
cmpl $0, _PiNrThreadsAwaitingReaping
je .L3
call _PiWakeupReaperThread@0
.L3:
/*
* Restore the saved register and exit
*/

View file

@ -188,9 +188,9 @@ KiIsObjectSignalled(DISPATCHER_HEADER * hdr,
}
}
VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus)
VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus, BOOL Unblock)
{
PKWAIT_BLOCK WaitBlock;
PKWAIT_BLOCK WaitBlock, PrevWaitBlock;
BOOLEAN WasWaiting = FALSE;
KeAcquireDispatcherDatabaseLock(FALSE);
@ -202,12 +202,18 @@ VOID KeRemoveAllWaitsThread(PETHREAD Thread, NTSTATUS WaitStatus)
}
while (WaitBlock != NULL)
{
RemoveEntryList(&WaitBlock->WaitListEntry);
if (WaitBlock->WaitListEntry.Flink != NULL && WaitBlock->WaitListEntry.Blink != NULL)
{
RemoveEntryList (&WaitBlock->WaitListEntry);
WaitBlock->WaitListEntry.Flink = WaitBlock->WaitListEntry.Blink = NULL;
}
PrevWaitBlock = WaitBlock;
WaitBlock = WaitBlock->NextWaitBlock;
PrevWaitBlock->NextWaitBlock = NULL;
}
Thread->Tcb.WaitBlockList = NULL;
if (WasWaiting)
if (WasWaiting && Unblock)
{
PsUnblockThread(Thread, &WaitStatus);
}
@ -243,6 +249,7 @@ KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr,
WaiterHead = CONTAINING_RECORD(EnumEntry, KWAIT_BLOCK, WaitListEntry);
DPRINT("current_entry %x current %x\n", EnumEntry, WaiterHead);
EnumEntry = EnumEntry->Flink;
assert(WaiterHead->Thread != NULL);
assert(WaiterHead->Thread->WaitBlockList != NULL);
Abandoned = FALSE;
@ -252,7 +259,11 @@ KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr,
DPRINT("WaitAny: Remove all wait blocks.\n");
for (Waiter = WaiterHead->Thread->WaitBlockList; Waiter; Waiter = Waiter->NextWaitBlock)
{
RemoveEntryList(&Waiter->WaitListEntry);
if (Waiter->WaitListEntry.Flink != NULL && Waiter->WaitListEntry.Blink != NULL)
{
RemoveEntryList(&Waiter->WaitListEntry);
Waiter->WaitListEntry.Flink = Waiter->WaitListEntry.Blink = NULL;
}
}
WaiterHead->Thread->WaitBlockList = NULL;
@ -287,8 +298,12 @@ KeDispatcherObjectWakeOneOrAll(DISPATCHER_HEADER * hdr,
{
for (Waiter = WaiterHead->Thread->WaitBlockList; Waiter; Waiter = Waiter->NextWaitBlock)
{
RemoveEntryList(&Waiter->WaitListEntry);
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)
@ -488,7 +503,7 @@ KeWaitForMultipleObjects(ULONG Count,
{
KeAcquireDispatcherDatabaseLock(FALSE);
/*
/*
* If we are going to wait alertably and a user apc is pending
* then return
*/

View file

@ -1,4 +1,4 @@
/* $Id: kill.c,v 1.62 2003/07/21 21:53:53 royce Exp $
/* $Id: kill.c,v 1.63 2003/08/18 11:23:32 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -158,10 +158,11 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus)
PLIST_ENTRY current_entry;
PKMUTANT Mutant;
CurrentThread = PsGetCurrentThread();
DPRINT("terminating %x\n",CurrentThread);
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
CurrentThread = PsGetCurrentThread();
CurrentThread->ExitStatus = ExitStatus;
Thread = KeGetCurrentThread();
@ -180,15 +181,18 @@ PsTerminateCurrentThread(NTSTATUS ExitStatus)
FALSE);
current_entry = Thread->MutantListHead.Flink;
}
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
KeAcquireDispatcherDatabaseLock(FALSE);
CurrentThread->Tcb.DispatcherHeader.SignalState = TRUE;
KeDispatcherObjectWake(&CurrentThread->Tcb.DispatcherHeader);
KeReleaseDispatcherDatabaseLock(FALSE);
KeReleaseDispatcherDatabaseLockAtDpcLevel(FALSE);
KeRemoveAllWaitsThread (CurrentThread, STATUS_UNSUCCESSFUL, FALSE);
KeAcquireSpinLock(&PiThreadListLock, &oldIrql);
PsDispatchThreadNoLock(THREAD_STATE_TERMINATED_1);
DPRINT1("Unexpected return, CurrentThread %x PsGetCurrentThread() %x\n", CurrentThread, PsGetCurrentThread());
DPRINT1("Unexpected return, CurrentThread %x PsGetCurrentThread() %x\n", CurrentThread, PsGetCurrentThread());
KEBUGCHECK(0);
}