Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenctxswitch.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS kernel 00004 * FILE: ntoskrnl/ke/i386/ctxswitch.S 00005 * PURPOSE: Thread Context Switching 00006 * 00007 * PROGRAMMERS: arty 00008 (i386 implementation by Alex Ionescu) 00009 */ 00010 00011 /* INCLUDES ******************************************************************/ 00012 00013 #include <ntoskrnl.h> 00014 #define NDEBUG 00015 #include <debug.h> 00016 #include <ppcmmu/mmu.h> 00017 00018 /*++ 00019 * KiThreadStartup 00020 * 00021 * The KiThreadStartup routine is the beginning of any thread. 00022 * 00023 * Params: 00024 * SystemRoutine - Pointer to the System Startup Routine. Either 00025 * PspUserThreadStartup or PspSystemThreadStartup 00026 * 00027 * StartRoutine - For Kernel Threads only, specifies the starting execution 00028 * point of the new thread. 00029 * 00030 * StartContext - For Kernel Threads only, specifies a pointer to variable 00031 * context data to be sent to the StartRoutine above. 00032 * 00033 * UserThread - Indicates whether or not this is a user thread. This tells 00034 * us if the thread has a context or not. 00035 * 00036 * TrapFrame - Pointer to the KTHREAD to which the caller wishes to 00037 * switch from. 00038 * 00039 * Returns: 00040 * Should never return for a system thread. Returns through the System Call 00041 * Exit Dispatcher for a user thread. 00042 * 00043 * Remarks: 00044 * If a return from a system thread is detected, a bug check will occur. 00045 * 00046 *--*/ 00047 00048 VOID 00049 NTAPI 00050 KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine, 00051 PKSTART_ROUTINE StartRoutine, 00052 PVOID StartContext, 00053 BOOLEAN UserThread, 00054 KTRAP_FRAME TrapFrame) 00055 { 00056 KeLowerIrql(APC_LEVEL); 00057 __asm__("mr 0,%0\n\t" 00058 "mr 3,%1\n\t" 00059 "mr 4,%2\n\t" 00060 "mr 5,%3\n\t" 00061 "mr 6,%4\n\t" 00062 "sc" : : 00063 "r" (0xf0000), /* Thread start function */ 00064 "r" (SystemRoutine), 00065 "r" (StartRoutine), 00066 "r" (StartContext), 00067 "r" (UserThread)); 00068 PspTerminateThreadByPointer(PsGetCurrentThread(), STATUS_THREAD_IS_TERMINATING, TRUE); 00069 } 00070 00071 /* Take a decrementer trap, and prepare the given trap frame, swapping 00072 * process and thread context as appropriate. */ 00073 VOID KiDecrementerTrapFinish(PKTRAP_FRAME TrapFrame); 00074 00075 VOID 00076 FASTCALL 00077 KiQueueReadyThread(IN PKTHREAD Thread, 00078 IN PKPRCB Prcb); 00079 00080 PKTHREAD KiLastThread = NULL; 00081 PKTRAP_FRAME KiLastThreadTrapFrame = NULL; 00082 00083 VOID 00084 NTAPI 00085 KiDecrementerTrap(PKTRAP_FRAME TrapFrame) 00086 { 00087 KIRQL Irql; 00088 PKPRCB Prcb = KeGetPcr()->Prcb; 00089 if (!KiLastThread) 00090 KiLastThread = KeGetCurrentThread(); 00091 00092 if (KiLastThread->State == Running) 00093 KiQueueReadyThread(KiLastThread, Prcb); 00094 00095 if (!KiLastThreadTrapFrame) 00096 KiLastThreadTrapFrame = Prcb->IdleThread->TrapFrame; 00097 00098 TrapFrame->OldIrql = KeGetCurrentIrql(); 00099 *KiLastThreadTrapFrame = *TrapFrame; 00100 00101 if (Prcb->NextThread) 00102 { 00103 Prcb->CurrentThread = Prcb->NextThread; 00104 Prcb->NextThread = NULL; 00105 } 00106 else 00107 Prcb->CurrentThread = Prcb->IdleThread; 00108 00109 Prcb->CurrentThread->State = Running; 00110 00111 KiLastThreadTrapFrame = Prcb->CurrentThread->TrapFrame; 00112 KiLastThread = Prcb->CurrentThread; 00113 00114 *TrapFrame = *KiLastThreadTrapFrame; 00115 Irql = KeGetCurrentIrql(); 00116 00117 if (Irql > TrapFrame->OldIrql) 00118 KfRaiseIrql(Irql); 00119 else if (Irql < TrapFrame->OldIrql) 00120 KfLowerIrql(Irql); 00121 00122 /* When we return, we'll go through rfi and be in new thread land */ 00123 __asm__("mtdec %0" : : "r" (0x1000000)); // Reset the trap 00124 } Generated on Sat May 26 2012 04:36:20 for ReactOS by
1.7.6.1
|