From d2cb3868b7543bfd95b8ab624ee68377bb314317 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 10 Sep 2006 14:43:12 +0000 Subject: [PATCH] - Add some definitions to ketypes.h - Fix multiple bugs in KTHREAD/KPROCESS where signed char values were marked as unsigned (and define SCHAR in ntdef.h) - Change prototype of KiSwapThread for future compatibility. - Fix prototype of KeSetIdealProcessorThread. - Add KiAcquireDispatcherLock, KiReleaseDispatcherLock, KiAcquireDispatcherLockAtDpcLevel, KiReleaseDispatcherLockFromDpcLevel to ke_x.h for future use. - Add KiInsertDeferredReadyList, KiRescheduleThread, KiSetThreadSwapBusy, KiRundownThread, KiCheckDeferredReadyList for future use. - Add KiAcquirePrcbLock, KiReleasePrcbLock, KiAcquireThreadLock, KiReleaseThreadLock for future use. - Add KxQueueReadyThread, KiSelectReadyThread for future use. - Add KiComputeNewPriority for future use. svn path=/trunk/; revision=24022 --- reactos/include/ndk/ketypes.h | 28 +- reactos/include/psdk/ntdef.h | 2 + reactos/ntoskrnl/include/internal/ke.h | 93 +++-- reactos/ntoskrnl/include/internal/ke_x.h | 461 +++++++++++++++++++++++ reactos/ntoskrnl/ke/gate.c | 2 +- reactos/ntoskrnl/ke/kthread.c | 10 +- reactos/ntoskrnl/ke/queue.c | 2 +- reactos/ntoskrnl/ke/wait.c | 6 +- 8 files changed, 553 insertions(+), 51 deletions(-) diff --git a/reactos/include/ndk/ketypes.h b/reactos/include/ndk/ketypes.h index 691b88a2e4f..d480a6382ee 100644 --- a/reactos/include/ndk/ketypes.h +++ b/reactos/include/ndk/ketypes.h @@ -59,6 +59,13 @@ Author: // #define KI_USER_SHARED_DATA_PHYSICAL 0x41000 +// +// Quantum values and decrements +// +#define MAX_QUANTUM 0x7F +#define WAIT_QUANTUM_DECREMENT 1 +#define CLOCK_QUANTUM_DECREMENT 3 + // // Kernel Feature Bits // @@ -679,13 +686,13 @@ typedef struct _KTHREAD volatile UCHAR NextProcessor; volatile UCHAR DeferredProcessor; UCHAR AdjustReason; - UCHAR AdjustIncrement; + SCHAR AdjustIncrement; KSPIN_LOCK ApcQueueLock; ULONG ContextSwitches; volatile UCHAR State; UCHAR NpxState; UCHAR WaitIrql; - UCHAR WaitMode; + SCHAR WaitMode; LONG WaitStatus; union { @@ -695,7 +702,7 @@ typedef struct _KTHREAD UCHAR Alertable; UCHAR WaitNext; UCHAR WaitReason; - UCHAR Priority; + SCHAR Priority; UCHAR EnableStackSwap; volatile UCHAR SwapBusy; UCHAR Alerted[2]; @@ -752,7 +759,7 @@ typedef struct _KTHREAD struct { UCHAR WaitBlockFill1[47]; - UCHAR PreviousMode; + SCHAR PreviousMode; }; struct { @@ -810,10 +817,10 @@ typedef struct _KTHREAD union { UCHAR SavedApcStateFill[23]; - CHAR FreezeCount; + SCHAR FreezeCount; }; }; - CHAR SuspendCount; + SCHAR SuspendCount; UCHAR UserIdealProcessor; #if (NTDDI_VERSION >= NTDDI_LONGHORN) union @@ -838,7 +845,7 @@ typedef struct _KTHREAD struct { UCHAR SuspendApcFill0[1]; - CHAR Quantum; + SCHAR Quantum; }; struct { @@ -888,6 +895,9 @@ typedef struct _KTHREAD } KTHREAD; #include +#define ASSERT_THREAD(object) \ + ASSERT((((object)->Header.Type & KOBJECT_TYPE_MASK) == ThreadObject)) + // // Kernel Process (KPROCESS) // @@ -923,8 +933,8 @@ typedef struct _KPROCESS }; ULONG ProcessFlags; }; - CHAR BasePriority; - CHAR QuantumReset; + SCHAR BasePriority; + SCHAR QuantumReset; UCHAR State; UCHAR ThreadSeed; UCHAR PowerState; diff --git a/reactos/include/psdk/ntdef.h b/reactos/include/psdk/ntdef.h index c2dfa45e510..8dcc53cf6d0 100644 --- a/reactos/include/psdk/ntdef.h +++ b/reactos/include/psdk/ntdef.h @@ -64,6 +64,8 @@ typedef STRING CANSI_STRING; typedef PSTRING PCANSI_STRING; typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS; typedef CONST CHAR *LPCCH, *PCCH; +typedef signed char SCHAR; +typedef SCHAR *PSCHAR; typedef enum _SECTION_INHERIT { ViewShare = 1, ViewUnmap = 2 diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 1559097c27d..b57dfcb43ba 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -132,28 +132,8 @@ extern VOID KiTrap2(VOID); /* MACROS *************************************************************************/ -/* - * On UP machines, we don't actually have a spinlock, we merely raise - * IRQL to DPC level. - */ -#ifdef CONFIG_SMP -#define KeInitializeDispatcher() KeInitializeSpinLock(&DispatcherDatabaseLock); -#define KeAcquireDispatcherDatabaseLock() KfAcquireSpinLock(&DispatcherDatabaseLock); -#define KeAcquireDispatcherDatabaseLockAtDpcLevel() \ - KeAcquireSpinLockAtDpcLevel (&DispatcherDatabaseLock); -#define KeReleaseDispatcherDatabaseLockFromDpcLevel() \ - KeReleaseSpinLockFromDpcLevel(&DispatcherDatabaseLock); -#define KeReleaseDispatcherDatabaseLock(OldIrql) \ - KiExitDispatcher(OldIrql); -#else -#define KeInitializeDispatcher() -#define KeAcquireDispatcherDatabaseLock() KeRaiseIrqlToDpcLevel(); -#define KeReleaseDispatcherDatabaseLock(OldIrql) KiExitDispatcher(OldIrql); -#define KeAcquireDispatcherDatabaseLockAtDpcLevel() -#define KeReleaseDispatcherDatabaseLockFromDpcLevel() -#endif - #define AFFINITY_MASK(Id) KiMask32Array[Id] +#define PRIORITY_MASK(Id) KiMask32Array[Id] /* The following macro initializes a dispatcher object's header */ #define KeInitializeDispatcherHeader(Header, t, s, State) \ @@ -166,8 +146,6 @@ extern VOID KiTrap2(VOID); InitializeListHead(&((Header)->WaitListHead)); \ } -extern KSPIN_LOCK DispatcherDatabaseLock; - #define KeEnterCriticalRegion() \ { \ PKTHREAD _Thread = KeGetCurrentThread(); \ @@ -209,9 +187,11 @@ extern KSPIN_LOCK DispatcherDatabaseLock; /* INTERNAL KERNEL FUNCTIONS ************************************************/ -/* threadsch.c ********************************************************************/ - -/* Thread Scheduler Functions */ +#define KeInitializeDispatcher() +#define KeAcquireDispatcherDatabaseLock() KeRaiseIrqlToDpcLevel(); +#define KeReleaseDispatcherDatabaseLock(OldIrql) KiExitDispatcher(OldIrql); +#define KeAcquireDispatcherDatabaseLockAtDpcLevel() +#define KeReleaseDispatcherDatabaseLockFromDpcLevel() /* Readies a Thread for Execution. */ BOOLEAN @@ -225,9 +205,10 @@ KiDispatchThread(ULONG NewThreadStatus); /* Finds a new thread to run */ NTSTATUS -NTAPI +FASTCALL KiSwapThread( - VOID + IN PKTHREAD Thread, + IN PKPRCB Prcb ); VOID @@ -238,7 +219,7 @@ NTSTATUS NTAPI KeSuspendThread(PKTHREAD Thread); -NTSTATUS +BOOLEAN FASTCALL KiSwapContext( IN PKTHREAD CurrentThread, @@ -253,6 +234,23 @@ VOID FASTCALL KiExitDispatcher(KIRQL OldIrql); +VOID +NTAPI +KiDeferredReadyThread(IN PKTHREAD Thread); + +KAFFINITY +NTAPI +KiSetAffinityThread( + IN PKTHREAD Thread, + IN KAFFINITY Affinity +); + +PKTHREAD +NTAPI +KiSelectNextThread( + IN PKPRCB Prcb +); + /* gmutex.c ********************************************************************/ VOID @@ -438,6 +436,30 @@ NTSTATUS NTAPI KeReleaseThread(PKTHREAD Thread); +VOID +NTAPI +KiSuspendRundown( + IN PKAPC Apc +); + +VOID +NTAPI +KiSuspendNop( + IN PKAPC Apc, + IN PKNORMAL_ROUTINE *NormalRoutine, + IN PVOID *NormalContext, + IN PVOID *SystemArgument1, + IN PVOID *SystemArgument2 +); + +VOID +NTAPI +KiSuspendThread( + IN PVOID NormalContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2 +); + LONG NTAPI KeQueryBasePriorityThread(IN PKTHREAD Thread); @@ -445,9 +467,9 @@ KeQueryBasePriorityThread(IN PKTHREAD Thread); VOID NTAPI KiSetPriorityThread( - PKTHREAD Thread, - KPRIORITY Priority, - PBOOLEAN Released + IN PKTHREAD Thread, + IN KPRIORITY Priority, + IN PBOOLEAN Released // hack ); BOOLEAN @@ -825,6 +847,13 @@ KiInitSystem( VOID ); +VOID +FASTCALL +KiInsertQueueApc( + IN PKAPC Apc, + IN KPRIORITY PriorityBoost +); + #include "ke_x.h" #endif /* __NTOSKRNL_INCLUDE_INTERNAL_KE_H */ diff --git a/reactos/ntoskrnl/include/internal/ke_x.h b/reactos/ntoskrnl/include/internal/ke_x.h index 4199406833f..214fb70d568 100644 --- a/reactos/ntoskrnl/include/internal/ke_x.h +++ b/reactos/ntoskrnl/include/internal/ke_x.h @@ -248,3 +248,464 @@ KiRecalculateDueTime(IN PLARGE_INTEGER OriginalDueTime, break; \ } \ } + +// +// Thread Scheduling Routines +// +#ifndef _CONFIG_SMP +KIRQL +FORCEINLINE +KiAcquireDispatcherLock(VOID) +{ + /* Raise to DPC level */ + return KeRaiseIrqlToDpcLevel(); +} + +VOID +FORCEINLINE +KiReleaseDispatcherLock(IN KIRQL OldIrql) +{ + /* Just exit the dispatcher */ + KiExitDispatcher(OldIrql); +} + +VOID +FORCEINLINE +KiAcquireDispatcherLockAtDpcLevel(VOID) +{ + /* This is a no-op at DPC Level for UP systems */ + return; +} + +VOID +FORCEINLINE +KiReleaseDispatcherLockFromDpcLevel(VOID) +{ + /* This is a no-op at DPC Level for UP systems */ + return; +} + +// +// This routine makes the thread deferred ready on the boot CPU. +// +FORCEINLINE +VOID +KiInsertDeferredReadyList(IN PKTHREAD Thread) +{ + /* Set the thread to deferred state and boot CPU */ + Thread->State = DeferredReady; + Thread->DeferredProcessor = 0; + + /* Make the thread ready immediately */ + KiDeferredReadyThread(Thread); +} + +FORCEINLINE +VOID +KiRescheduleThread(IN BOOLEAN NewThread, + IN ULONG Cpu) +{ + /* This is meaningless on UP systems */ + UNREFERENCED_PARAMETER(NewThread); + UNREFERENCED_PARAMETER(Cpu); +} + +// +// This routine protects against multiple CPU acquires, it's meaningless on UP. +// +FORCEINLINE +VOID +KiSetThreadSwapBusy(IN PKTHREAD Thread) +{ + UNREFERENCED_PARAMETER(Thread); +} + +// +// This routine protects against multiple CPU acquires, it's meaningless on UP. +// +FORCEINLINE +VOID +KiAcquirePrcbLock(IN PKPRCB Prcb) +{ + UNREFERENCED_PARAMETER(Prcb); +} + +// +// This routine protects against multiple CPU acquires, it's meaningless on UP. +// +FORCEINLINE +VOID +KiReleasePrcbLock(IN PKPRCB Prcb) +{ + UNREFERENCED_PARAMETER(Prcb); +} + +// +// This routine protects against multiple CPU acquires, it's meaningless on UP. +// +FORCEINLINE +VOID +KiAcquireThreadLock(IN PKTHREAD Thread) +{ + UNREFERENCED_PARAMETER(Thread); +} + +// +// This routine protects against multiple CPU acquires, it's meaningless on UP. +// +FORCEINLINE +VOID +KiReleaseThreadLock(IN PKTHREAD Thread) +{ + UNREFERENCED_PARAMETER(Thread); +} + +FORCEINLINE +VOID +KiCheckDeferredReadyList(IN PKPRCB Prcb) +{ + /* There are no deferred ready lists on UP systems */ + UNREFERENCED_PARAMETER(Prcb); +} + +FORCEINLINE +VOID +KiRundownThread(IN PKTHREAD Thread) +{ + /* Check if this is the NPX Thread */ + if (KeGetCurrentPrcb()->NpxThread == Thread) + { + /* Clear it */ + KeGetCurrentPrcb()->NpxThread = NULL; +#ifdef __GNUC__ + __asm__("fninit\n\t"); +#else + __asm fninit; +#endif + } +} + +#else + +KIRQL +FORCEINLINE +KiAcquireDispatcherLock(VOID) +{ + /* Raise to synchronization level and acquire the dispatcher lock */ + return KeAcquireQueuedSpinLockRaiseToSynch(LockQueueDispatcherLock); +} + +VOID +FORCEINLINE +KiReleaseDispatcherLock(IN KIRQL OldIrql) +{ + /* First release the lock */ + KeReleaseQueuedSpinLockFromDpcLevel(&KeGetCurrentPrcb()-> + LockQueue[LockQueueDispatcherLock]); + + /* Then exit the dispatcher */ + KiExitDispatcher(OldIrql); +} + +// +// This routine inserts a thread into the deferred ready list of the given CPU +// +FORCEINLINE +VOID +KiInsertDeferredReadyList(IN PKTHREAD Thread) +{ + PKPRCB Prcb = KeGetCurrentPrcb(); + + /* Set the thread to deferred state and CPU */ + Thread->State = DeferredReady; + Thread->DeferredProcessor = Prcb->Number; + + /* Add it on the list */ + PushEntryList(&Prcb->DeferredReadyListHead, &Thread->SwapListEntry); +} + +FORCEINLINE +VOID +KiRescheduleThread(IN BOOLEAN NewThread, + IN ULONG Cpu) +{ + /* Check if a new thread needs to be scheduled on a different CPU */ + if ((NewThread) && !(KeGetPcr()->Number == Cpu)) + { + /* Send an IPI to request delivery */ + KiIpiSendRequest(AFFINITY_MASK(Cpu), IPI_DPC); + } +} + +// +// This routine sets the current thread in a swap busy state, which ensure that +// nobody else tries to swap it concurrently. +// +FORCEINLINE +VOID +KiSetThreadSwapBusy(IN PKTHREAD Thread) +{ + /* Make sure nobody already set it */ + ASSERT(Thread->SwapBusy == FALSE); + + /* Set it ourselves */ + Thread->SwapBusy = TRUE; +} + +// +// This routine acquires the PRCB lock so that only one caller can touch +// volatile PRCB data. +// +// Since this is a simple optimized spin-lock, it must be be only acquired +// at dispatcher level or higher! +// +FORCEINLINE +VOID +KiAcquirePrcbLock(IN PKPRCB Prcb) +{ + /* Make sure we're at a safe level to touch the PRCB lock */ + ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); + + /* Start acquire loop */ + for (;;) + { + /* Acquire the lock and break out if we acquired it first */ + if (!InterlockedExchange(&Prcb->PrcbLock, 1)) break; + + /* Loop until the other CPU releases it */ + do + { + /* Let the CPU know that this is a loop */ + YieldProcessor(); + } while (Prcb->PrcbLock); + } +} + +// +// This routine releases the PRCB lock so that other callers can touch +// volatile PRCB data. +// +// Since this is a simple optimized spin-lock, it must be be only acquired +// at dispatcher level or higher! +// +FORCEINLINE +VOID +KiReleasePrcbLock(IN PKPRCB Prcb) +{ + /* Make sure it's acquired! */ + ASSERT(Prcb->PrcbLock != 0); + + /* Release it */ + InterlockedAnd(&Prcb->PrcbLock, 0); +} + +// +// This routine acquires the thread lock so that only one caller can touch +// volatile thread data. +// +// Since this is a simple optimized spin-lock, it must be be only acquired +// at dispatcher level or higher! +// +FORCEINLINE +VOID +KiAcquireThreadLock(IN PKTHREAD Thread) +{ + /* Make sure we're at a safe level to touch the thread lock */ + ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); + + /* Start acquire loop */ + for (;;) + { + /* Acquire the lock and break out if we acquired it first */ + if (!InterlockedExchange(&Thread->ThreadLock, 1)) break; + + /* Loop until the other CPU releases it */ + do + { + /* Let the CPU know that this is a loop */ + YieldProcessor(); + } while (Thread->ThreadLock); + } +} + +// +// This routine releases the thread lock so that other callers can touch +// volatile thread data. +// +// Since this is a simple optimized spin-lock, it must be be only acquired +// at dispatcher level or higher! +// +FORCEINLINE +VOID +KiReleaseThreadLock(IN PKTHREAD Thread) +{ + /* Release it */ + InterlockedAnd(&Thread->ThreadLock, 0); +} + +FORCEINLINE +VOID +KiCheckDeferredReadyList(IN PKPRCB Prcb) +{ + /* Scan the deferred ready lists if required */ + if (Prcb->DeferredReadyListHead.Next) KiProcessDeferredReadyList(Prcb); +} + +#endif + +// +// This routine queues a thread that is ready on the PRCB's ready lists. +// If this thread cannot currently run on this CPU, then the thread is +// added to the deferred ready list instead. +// +// This routine must be entered with the PRCB lock held and it will exit +// with the PRCB lock released! +// +FORCEINLINE +VOID +KxQueueReadyThread(IN PKTHREAD Thread, + IN PKPRCB Prcb) +{ + BOOLEAN Preempted; + KPRIORITY Priority; + + /* Sanity checks */ + ASSERT(Prcb == KeGetCurrentPrcb()); + ASSERT(Thread->State == Running); + ASSERT(Thread->NextProcessor == Prcb->Number); + + /* Check if this thread is allowed to run in this CPU */ +#ifdef _CONFIG_SMP + if ((Thread->Affinity) & (Prcb->SetMember)) +#else + if (TRUE) +#endif + { + /* Set thread ready for execution */ + Thread->State = Ready; + + /* Save current priority and if someone had pre-empted it */ + Priority = Thread->Priority; + Preempted = Thread->Preempted; + + /* We're not pre-empting now, and set the wait time */ + Thread->Preempted = FALSE; + Thread->WaitTime = KeTickCount.LowPart; + + /* Sanity check */ + ASSERT((Priority >= 0) && (Priority <= HIGH_PRIORITY)); + + /* Insert this thread in the appropriate order */ + Preempted ? InsertHeadList(&Prcb->DispatcherReadyListHead[Priority], + &Thread->WaitListEntry) : + InsertTailList(&Prcb->DispatcherReadyListHead[Priority], + &Thread->WaitListEntry); + + /* Update the ready summary */ + Prcb->ReadySummary |= PRIORITY_MASK(Priority); + + /* Sanity check */ + ASSERT(Priority == Thread->Priority); + + /* Release the PRCB lock */ + KiReleasePrcbLock(Prcb); + } + else + { + /* Otherwise, prepare this thread to be deferred */ + Thread->State = DeferredReady; + Thread->DeferredProcessor = Prcb->Number; + + /* Release the lock and defer scheduling */ + KiReleasePrcbLock(Prcb); + KiDeferredReadyThread(Thread); + } +} + +// +// This routine scans for an appropriate ready thread to select at the +// given priority and for the given CPU. +// +FORCEINLINE +PKTHREAD +KiSelectReadyThread(IN KPRIORITY Priority, + IN PKPRCB Prcb) +{ + LONG PriorityMask, PrioritySet, HighPriority; + PLIST_ENTRY ListEntry; + PKTHREAD Thread; + + /* Save the current mask and get the priority set for the CPU */ + PriorityMask = Priority; + PrioritySet = Prcb->ReadySummary >> (UCHAR)Priority; + if (!PrioritySet) return NULL; + + /* Get the highest priority possible */ + BitScanReverse(&HighPriority, PrioritySet); + ASSERT((PrioritySet & PRIORITY_MASK(HighPriority)) != 0); + HighPriority += PriorityMask; + + /* Make sure the list isn't at highest priority */ + ASSERT(IsListEmpty(&Prcb->DispatcherReadyListHead[HighPriority]) == FALSE); + + /* Get the first thread on the list */ + ListEntry = &Prcb->DispatcherReadyListHead[HighPriority]; + Thread = CONTAINING_RECORD(ListEntry, KTHREAD, WaitListEntry); + + /* Make sure this thread is here for a reason */ + ASSERT(HighPriority == Thread->Priority); + ASSERT(Thread->Affinity & AFFINITY_MASK(Prcb->Number)); + ASSERT(Thread->NextProcessor == Prcb->Number); + + /* Remove it from the list */ + RemoveEntryList(&Thread->WaitListEntry); + if (IsListEmpty(&Thread->WaitListEntry)) + { + /* The list is empty now, reset the ready summary */ + Prcb->ReadySummary ^= PRIORITY_MASK(HighPriority); + } + + /* Sanity check and return the thread */ + ASSERT((Thread == NULL) || + (Thread->BasePriority == 0) || + (Thread->Priority != 0)); + return Thread; +} + +// +// This routine computes the new priority for a thread. It is only valid for +// threads with priorities in the dynamic priority range. +// +SCHAR +FORCEINLINE +KiComputeNewPriority(IN PKTHREAD Thread) +{ + SCHAR Priority; + + /* Priority sanity checks */ + ASSERT((Thread->PriorityDecrement >= 0) && + (Thread->PriorityDecrement <= Thread->Priority)); + ASSERT((Thread->Priority < LOW_REALTIME_PRIORITY) ? + TRUE : (Thread->PriorityDecrement == 0)); + + /* Get the current priority */ + Priority = Thread->Priority; + if (Priority < LOW_REALTIME_PRIORITY) + { + /* Set the New Priority and add the Priority Decrement */ + Priority += (Priority - Thread->PriorityDecrement - 1); + + /* Don't go out of bounds */ + if (Priority < Thread->BasePriority) Priority = Thread->BasePriority; + + /* Reset the priority decrement */ + Thread->PriorityDecrement = 0; + } + + /* Sanity check */ + ASSERT((Thread->BasePriority == 0) || (Priority != 0)); + + /* Return the new priority */ + return Priority; +} + diff --git a/reactos/ntoskrnl/ke/gate.c b/reactos/ntoskrnl/ke/gate.c index cae5497c9e7..a9583caf6ef 100644 --- a/reactos/ntoskrnl/ke/gate.c +++ b/reactos/ntoskrnl/ke/gate.c @@ -85,7 +85,7 @@ KeWaitForGate(IN PKGATE Gate, if (CurrentThread->Queue) KiWakeQueue(CurrentThread->Queue); /* Find a new thread to run */ - Status = KiSwapThread(); + Status = KiSwapThread(CurrentThread, KeGetCurrentPrcb()); /* Check if we were executing an APC */ if (Status != STATUS_KERNEL_APC) return; diff --git a/reactos/ntoskrnl/ke/kthread.c b/reactos/ntoskrnl/ke/kthread.c index 4b621debd7d..b6a211409a4 100644 --- a/reactos/ntoskrnl/ke/kthread.c +++ b/reactos/ntoskrnl/ke/kthread.c @@ -200,10 +200,10 @@ KiDispatchThreadNoLock(ULONG NewThreadStatus) } NTSTATUS -NTAPI -KiSwapThread(VOID) +FASTCALL +KiSwapThread(IN PKTHREAD CurrentThread, + IN PKPRCB Prcb) { - PKTHREAD CurrentThread = KeGetCurrentThread(); BOOLEAN ApcState; /* Find a new thread to run */ @@ -1068,10 +1068,10 @@ KeRevertToUserAffinityThread(VOID) /* * @implemented */ -CCHAR +UCHAR STDCALL KeSetIdealProcessorThread(IN PKTHREAD Thread, - IN CCHAR Processor) + IN UCHAR Processor) { CCHAR PreviousIdealProcessor; KIRQL OldIrql; diff --git a/reactos/ntoskrnl/ke/queue.c b/reactos/ntoskrnl/ke/queue.c index 3149645b1f0..041af562cc8 100644 --- a/reactos/ntoskrnl/ke/queue.c +++ b/reactos/ntoskrnl/ke/queue.c @@ -426,7 +426,7 @@ KeRemoveQueue(IN PKQUEUE Queue, /* Find a new thread to run */ KiAddThreadToWaitList(Thread, Swappable); - Status = KiSwapThread(); + Status = KiSwapThread(Thread, KeGetCurrentPrcb()); /* Reset the wait reason */ Thread->WaitReason = 0; diff --git a/reactos/ntoskrnl/ke/wait.c b/reactos/ntoskrnl/ke/wait.c index 92749c23bf3..06bd18c4996 100644 --- a/reactos/ntoskrnl/ke/wait.c +++ b/reactos/ntoskrnl/ke/wait.c @@ -352,7 +352,7 @@ KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, /* Find a new thread to run */ KiAddThreadToWaitList(CurrentThread, Swappable); - WaitStatus = KiSwapThread(); + WaitStatus = KiSwapThread(CurrentThread, KeGetCurrentPrcb()); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Check if we were executing an APC or if we timed out */ @@ -540,7 +540,7 @@ KeWaitForSingleObject(IN PVOID Object, /* Find a new thread to run */ KiAddThreadToWaitList(CurrentThread, Swappable); - WaitStatus = KiSwapThread(); + WaitStatus = KiSwapThread(CurrentThread, KeGetCurrentPrcb()); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Check if we were executing an APC */ @@ -828,7 +828,7 @@ KeWaitForMultipleObjects(IN ULONG Count, /* Find a new thread to run */ KiAddThreadToWaitList(CurrentThread, Swappable); - WaitStatus = KiSwapThread(); + WaitStatus = KiSwapThread(CurrentThread, KeGetCurrentPrcb()); ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); /* Check if we were executing an APC */