ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ctxswitch.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.