From 8d372c227128ad6d3ec50cbc52cb34cf1e57e8d6 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Thu, 13 Jul 2006 22:52:18 +0000 Subject: [PATCH] - Fix utterly messed up unblocking/readying thread logic. - KiUnblockThread becomes KiReadyThread and doesn't perform priority modifications anymore. Also removed a large block of code that was #if 0ed out. - KiAbortWaitThread now does priority modifications (and better then before), then calls KiReadyThread. - Inserting a queue now *READIES A THREAD ONLY* instead of removing all its waits! svn path=/trunk/; revision=23055 --- reactos/ntoskrnl/include/internal/ke.h | 15 ++--- reactos/ntoskrnl/ke/gate.c | 4 +- reactos/ntoskrnl/ke/kthread.c | 82 ++------------------------ reactos/ntoskrnl/ke/queue.c | 2 +- reactos/ntoskrnl/ke/wait.c | 61 ++++++++++++++++++- reactos/ntoskrnl/ps/idle.c | 2 +- reactos/ntoskrnl/ps/thread.c | 2 +- 7 files changed, 75 insertions(+), 93 deletions(-) diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index b8c97e4aabe..651d8845eed 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -133,14 +133,9 @@ KiSwapThread( VOID ); -/* Removes a thread out of a block state. */ VOID -STDCALL -KiUnblockThread( - PKTHREAD Thread, - PNTSTATUS WaitStatus, - KPRIORITY Increment -); +NTAPI +KiReadyThread(IN PKTHREAD Thread); NTSTATUS STDCALL @@ -331,9 +326,9 @@ KiTestAlert(VOID); VOID FASTCALL KiAbortWaitThread( - PKTHREAD Thread, - NTSTATUS WaitStatus, - KPRIORITY Increment + IN PKTHREAD Thread, + IN NTSTATUS WaitStatus, + IN KPRIORITY Increment ); VOID diff --git a/reactos/ntoskrnl/ke/gate.c b/reactos/ntoskrnl/ke/gate.c index e691cf7d56b..cae5497c9e7 100644 --- a/reactos/ntoskrnl/ke/gate.c +++ b/reactos/ntoskrnl/ke/gate.c @@ -132,8 +132,8 @@ KeSignalGateBoostPriority(IN PKGATE Gate) /* Increment the Queue's active threads */ if (WaitThread->Queue) WaitThread->Queue->CurrentCount++; - /* Reschedule the Thread */ - KiUnblockThread(WaitThread, &WaitStatus, EVENT_INCREMENT); + /* FIXME: This isn't really correct!!! */ + KiAbortWaitThread(WaitThread, WaitStatus, EVENT_INCREMENT); } quit: diff --git a/reactos/ntoskrnl/ke/kthread.c b/reactos/ntoskrnl/ke/kthread.c index b1e1f9fc755..d464d1a5054 100644 --- a/reactos/ntoskrnl/ke/kthread.c +++ b/reactos/ntoskrnl/ke/kthread.c @@ -202,84 +202,12 @@ KiDispatchThread(ULONG NewThreadStatus) } VOID -STDCALL -KiUnblockThread(PKTHREAD Thread, - PNTSTATUS WaitStatus, - KPRIORITY Increment) +NTAPI +KiReadyThread(IN PKTHREAD Thread) { - if (Terminated == Thread->State) { - - DPRINT1("Can't unblock thread 0x%x because it's terminating\n", - Thread); - - } else if (Ready == Thread->State || - Running == Thread->State) { - - DPRINT1("Can't unblock thread 0x%x because it's %s\n", - Thread, (Thread->State == Ready ? "ready" : "running")); - - } else { - - LONG Processor; - KAFFINITY Affinity; - - /* FIXME: This propably isn't the right way to do it... */ - /* No it's not... i'll fix it later-- Alex */ - if (Thread->Priority < LOW_REALTIME_PRIORITY && - Thread->BasePriority < LOW_REALTIME_PRIORITY - 2) { - - if (!Thread->PriorityDecrement && !Thread->DisableBoost) { - - Thread->Priority = Thread->BasePriority + Increment; - Thread->PriorityDecrement = Increment; - } - - /* Also decrease quantum */ - Thread->Quantum--; - - } else { - - Thread->Quantum = Thread->QuantumReset; - } - - if (WaitStatus != NULL) { - - Thread->WaitStatus = *WaitStatus; - } - - Thread->State = Ready; - KiInsertIntoThreadList(Thread->Priority, Thread); - Processor = KeGetCurrentProcessorNumber(); - Affinity = Thread->Affinity; - - if (!(IdleProcessorMask & (1 << Processor) & Affinity) && - (IdleProcessorMask & ~(1 << Processor) & Affinity)) { - - LONG i; - - for (i = 0; i < KeNumberProcessors - 1; i++) { - - Processor++; - - if (Processor >= KeNumberProcessors) { - - Processor = 0; - } - - if (IdleProcessorMask & (1 << Processor) & Affinity) { -#if 0 - /* FIXME: - * Reschedule the threads on an other processor - */ - KeReleaseDispatcherDatabaseLockFromDpcLevel(); - KiRequestReschedule(Processor); - KeAcquireDispatcherDatabaseLockAtDpcLevel(); -#endif - break; - } - } - } - } + /* Makes a thread ready */ + Thread->State = Ready; + KiInsertIntoThreadList(Thread->Priority, Thread); } VOID diff --git a/reactos/ntoskrnl/ke/queue.c b/reactos/ntoskrnl/ke/queue.c index ec1a0372640..08223d292d7 100644 --- a/reactos/ntoskrnl/ke/queue.c +++ b/reactos/ntoskrnl/ke/queue.c @@ -117,7 +117,7 @@ KiInsertQueue(IN PKQUEUE Queue, } /* Reschedule the Thread */ - KiUnblockThread(Thread, NULL, 0); + KiReadyThread(Thread); } else { diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 312b2c66c72..e5bdf092a6b 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -127,6 +127,7 @@ KiAbortWaitThread(IN PKTHREAD Thread, { PKWAIT_BLOCK WaitBlock; PKTIMER Timer; + LONG NewPriority; /* Update wait status */ Thread->WaitStatus |= WaitStatus; @@ -158,8 +159,66 @@ KiAbortWaitThread(IN PKTHREAD Thread, /* Increment the Queue's active threads */ if (Thread->Queue) Thread->Queue->CurrentCount++; + /* Check if this is a non-RT thread */ + if (Thread->Priority < LOW_REALTIME_PRIORITY) + { + /* Check if boosting is enabled and we can boost */ + if (!(Thread->DisableBoost) && !(Thread->PriorityDecrement)) + { + /* We can boost, so calculate the new priority */ + NewPriority = Thread->BasePriority + Increment; + if (NewPriority > Thread->Priority) + { + /* Make sure the new priority wouldn't push the thread to RT */ + if (NewPriority >= LOW_REALTIME_PRIORITY) + { + /* Set it just before the RT zone */ + Thread->Priority = LOW_REALTIME_PRIORITY - 1; + } + else + { + /* Otherwise, set our calculated priority */ + Thread->Priority = NewPriority; + } + } + } + + /* Check if this is a high-priority thread */ + if (Thread->BasePriority >= 14) + { + /* It is, simply reset the quantum */ + Thread->Quantum = Thread->QuantumReset; + } + else + { + /* Otherwise, decrease quantum */ + Thread->Quantum--; + if (Thread->Quantum <= 0) + { + /* We've went below 0, reset it */ + Thread->Quantum = Thread->QuantumReset; + + /* Apply per-quantum priority decrement */ + Thread->Priority -= (Thread->PriorityDecrement + 1); + if (Thread->Priority < Thread->BasePriority) + { + /* We've went too low, reset it */ + Thread->Priority = Thread->BasePriority; + } + + /* Delete per-quantum decrement */ + Thread->PriorityDecrement = 0; + } + } + } + else + { + /* For real time threads, just reset the quantum */ + Thread->Quantum = Thread->QuantumReset; + } + /* Reschedule the Thread */ - KiUnblockThread(Thread, NULL, Increment); + KiReadyThread(Thread); } VOID diff --git a/reactos/ntoskrnl/ps/idle.c b/reactos/ntoskrnl/ps/idle.c index 2b1d39c51b7..389f4ef9d42 100644 --- a/reactos/ntoskrnl/ps/idle.c +++ b/reactos/ntoskrnl/ps/idle.c @@ -110,7 +110,7 @@ PsInitIdleThread(VOID) FALSE); oldIrql = KeAcquireDispatcherDatabaseLock (); - KiUnblockThread(&IdleThread->Tcb, NULL, 0); + KiReadyThread(&IdleThread->Tcb); KeReleaseDispatcherDatabaseLock(oldIrql); KeGetCurrentPrcb()->IdleThread = &IdleThread->Tcb; diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index 4c927482825..d79c9b90f5e 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -353,7 +353,7 @@ PspCreateThread(OUT PHANDLE ThreadHandle, /* Dispatch thread */ OldIrql = KeAcquireDispatcherDatabaseLock (); - KiUnblockThread(&Thread->Tcb, NULL, 0); + KiReadyThread(&Thread->Tcb); KeReleaseDispatcherDatabaseLock(OldIrql); /* Return */