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/…
==============================================================================
--- 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=4952…
==============================================================================
--- 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=495…
==============================================================================
--- 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 */