Author: sir_richard Date: Mon Nov 8 11:56:22 2010 New Revision: 49523
URL: http://svn.reactos.org/svn/reactos?rev=49523&view=rev Log: [NTOS]: Optimize new context switching code to avoid wasted cycles.
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h trunk/reactos/ntoskrnl/ke/dpc.c trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S trunk/reactos/ntoskrnl/ke/i386/thrdini.c trunk/reactos/ntoskrnl/ke/thrdschd.c trunk/reactos/ntoskrnl/ke/wait.c
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/k... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] Mon Nov 8 11:56:22 2010 @@ -298,8 +298,8 @@ BOOLEAN FASTCALL KiSwapContext( - IN PKTHREAD CurrentThread, - IN PKTHREAD NewThread + IN KIRQL WaitIrql, + IN PKTHREAD CurrentThread );
VOID
Modified: trunk/reactos/ntoskrnl/ke/dpc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/dpc.c?rev=49523... ============================================================================== --- trunk/reactos/ntoskrnl/ke/dpc.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/dpc.c [iso-8859-1] Mon Nov 8 11:56:22 2010 @@ -534,7 +534,7 @@ Thread->WaitIrql = APC_LEVEL;
/* Swap threads */ - KiSwapContext(Thread, NextThread); + KiSwapContext(APC_LEVEL, Thread);
/* Lower IRQL back to DISPATCH_LEVEL */ KeLowerIrql(DISPATCH_LEVEL);
Modified: trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/ctxswitch.... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/i386/ctxswitch.S [iso-8859-1] Mon Nov 8 11:56:22 2010 @@ -13,70 +13,20 @@ #include <ndk/asm.h> .intel_syntax noprefix
-#define Ready 1 -#define Running 2 -#define WrDispatchInt 0x1F - /* FUNCTIONS ****************************************************************/
-/*++ - * KiSwapContextInternal - * - * The KiSwapContextInternal routine switches context to another thread. - * - * Params: - * ESI - Pointer to the KTHREAD to which the caller wishes to - * switch to. - * EDI - Pointer to the KTHREAD to which the caller wishes to - * switch from. - * - * Returns: - * None. - * - * Remarks: - * Absolutely all registers except ESP can be trampled here for maximum code flexibility. - * - *--*/ .globl @KiSwapContextInternal@0 .func @KiSwapContextInternal@0, @KiSwapContextInternal@0 @KiSwapContextInternal@0: - /* Set APC Bypass Disable and old thread pointer */ - mov edx, edi - or dl, cl - /* Build switch frame */ sub esp, 2 * 4 mov ecx, esp - call @KiSwapContextEntry@8 - mov ecx, 0xB00BFACA - jmp $ + jmp @KiSwapContextEntry@8 .endfunc
-/*++ - * KiSwapContext - * - * The KiSwapContext routine switches context to another thread. - * - * Params: - * TargetThread - Pointer to the KTHREAD to which the caller wishes to - * switch to. - * - * Returns: - * The WaitStatus of the Target Thread. - * - * Remarks: - * This is a wrapper around KiSwapContextInternal which will save all the - * non-volatile registers so that the Internal function can use all of - * them. It will also save the old current thread and set the new one. - * - * The calling thread does not return after KiSwapContextInternal until - * another thread switches to IT. - * - *--*/ .globl @KiSwapContext@8 .func @KiSwapContext@8, @KiSwapContext@8 @KiSwapContext@8: - /* Save 4 registers */ sub esp, 4 * 4
@@ -86,17 +36,8 @@ mov [esp+4], edi mov [esp+0], ebp
- /* Get the current KPCR */ - mov ebx, fs:[KPCR_SELF] - - /* Get the Current Thread */ - mov edi, ecx - - /* Get the New Thread */ - mov esi, edx - /* Get the wait IRQL */ - movzx ecx, byte ptr [edi+KTHREAD_WAIT_IRQL] + or dl, cl
/* Do the swap with the registers correctly setup */ call @KiSwapContextInternal@0 @@ -112,10 +53,21 @@ ret .endfunc
+.globl @KiSwitchThreads@8 +.func @KiSwitchThreads@8, @KiSwitchThreads@8 +@KiSwitchThreads@8: + /* Load the new kernel stack and switch OS to new thread */ + mov esp, edx + call @KiSwapContextExit@8 + + /* Now we're on the new thread. Return to the caller to restore registers */ + add esp, 2 * 4 + ret +.endfunc + .globl @KiRetireDpcListInDpcStack@8 .func @KiRetireDpcListInDpcStack@8, @KiRetireDpcListInDpcStack@8 @KiRetireDpcListInDpcStack@8: - /* Switch stacks and retire DPCs */ mov eax, esp mov esp, edx @@ -140,20 +92,6 @@ jmp $ .endfunc
-.globl @KiSwitchThreads@8 -.func @KiSwitchThreads@8, @KiSwitchThreads@8 -@KiSwitchThreads@8: - - /* Load the new kernel stack and switch OS to new thread */ - mov esp, [edx+KTHREAD_KERNEL_STACK] - mov edx, esp - call @KiSwapContextExit@8 - - /* Now we're on the new thread. Return to the caller to restore registers */ - add esp, 2 * 4 - ret -.endfunc - .globl @Ki386BiosCallReturnAddress@4 @Ki386BiosCallReturnAddress@4:
Modified: trunk/reactos/ntoskrnl/ke/i386/thrdini.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/thrdini.c?... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/thrdini.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/i386/thrdini.c [iso-8859-1] Mon Nov 8 11:56:22 2010 @@ -309,7 +309,7 @@ NewThread->State = Running;
/* Switch away from the idle thread */ - KiSwapContext(OldThread, NewThread); + KiSwapContext(APC_LEVEL, OldThread);
/* We are back in the idle thread -- disable interrupts again */ _enable(); @@ -416,9 +416,6 @@ PKTHREAD OldThread, NewThread; ULONG Cr0, NewCr0;
- /* Switch threads, check for APC disable */ - ASSERT(OldThreadAndApcFlag &~ 1); - /* Save APC bypass disable */ SwitchFrame->ApcBypassDisable = OldThreadAndApcFlag & 3; SwitchFrame->ExceptionList = Pcr->NtTib.ExceptionList; @@ -451,7 +448,7 @@
/* Now enable interrupts and do the switch */ _enable(); - KiSwitchThreads(OldThread, NewThread); + KiSwitchThreads(OldThread, NewThread->KernelStack); }
VOID @@ -509,8 +506,8 @@ /* Make the old thread ready */ KxQueueReadyThread(OldThread, Prcb);
- /* Swap to the new thread. FIXME: APC Bypass */ - KiSwapContext(OldThread, NewThread); + /* Swap to the new thread */ + KiSwapContext(APC_LEVEL, OldThread); } }
Modified: trunk/reactos/ntoskrnl/ke/thrdschd.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/thrdschd.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ke/thrdschd.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/thrdschd.c [iso-8859-1] Mon Nov 8 11:56:22 2010 @@ -387,7 +387,7 @@ WaitIrql = CurrentThread->WaitIrql;
/* Swap contexts */ - ApcState = KiSwapContext(CurrentThread, NextThread); + ApcState = KiSwapContext(WaitIrql, CurrentThread);
/* Get the wait status */ WaitStatus = CurrentThread->WaitStatus; @@ -754,7 +754,7 @@ ASSERT(OldIrql <= DISPATCH_LEVEL);
/* Swap to new thread */ - KiSwapContext(Thread, NextThread); + KiSwapContext(APC_LEVEL, Thread); Status = STATUS_SUCCESS; } else
Modified: trunk/reactos/ntoskrnl/ke/wait.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/wait.c?rev=4952... ============================================================================== --- trunk/reactos/ntoskrnl/ke/wait.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ke/wait.c [iso-8859-1] Mon Nov 8 11:56:22 2010 @@ -249,7 +249,7 @@ Thread->WaitIrql = OldIrql;
/* Swap threads and check if APCs were pending */ - PendingApc = KiSwapContext(Thread, NextThread); + PendingApc = KiSwapContext(OldIrql, Thread); if (PendingApc) { /* Lower only to APC */