Page principale | Liste des namespaces | Hiérarchie des classes | Liste des classes | Répertoires | Liste des fichiers | Membres de namespace | Membres de classe | Membres de fichier

thread.h

Aller à la documentation de ce fichier.
00001 // thread.h 
00002 //      Data structures for managing threads.  A thread represents
00003 //      sequential execution of code within a program.
00004 //      So the state of a thread includes the program counter,
00005 //      the processor registers, and the execution stack.
00006 //      
00007 //      Note that because we allocate a fixed size stack for each
00008 //      thread, it is possible to overflow the stack -- for instance,
00009 //      by recursing to too deep a level.  The most common reason
00010 //      for this occuring is allocating large data structures
00011 //      on the stack.  For instance, this will cause problems:
00012 //
00013 //              void foo() { int buf[1000]; ...}
00014 //
00015 //      Instead, you should allocate all data structures dynamically:
00016 //
00017 //              void foo() { int *buf = new int[1000]; ...}
00018 //
00019 //
00020 //      Bad things happen if you overflow the stack, and in the worst 
00021 //      case, the problem may not be caught explicitly.  Instead,
00022 //      the only symptom may be bizarre segmentation faults.  (Of course,
00023 //      other problems can cause seg faults, so that isn't a sure sign
00024 //      that your thread stacks are too small.)
00025 //      
00026 //      One thing to try if you find yourself with seg faults is to
00027 //      increase the size of thread stack -- ThreadStackSize.
00028 //
00029 //      In this interface, forking a thread takes two steps.
00030 //      We must first allocate a data structure for it: "t = new Thread".
00031 //      Only then can we do the fork: "t->fork(f, arg)".
00032 //
00033 // Copyright (c) 1992-1996 The Regents of the University of California.
00034 // All rights reserved.  See copyright.h for copyright notice and limitation 
00035 // of liability and disclaimer of warranty provisions.
00036 
00037 #ifndef THREAD_H
00038 #define THREAD_H
00039 
00040 #include "copyright.h"
00041 #include "utility.h"
00042 #include "sysdep.h"
00043 
00044 #include "machine.h"
00045 #include "addrspace.h"
00046 
00047 // CPU register state to be saved on context switch.  
00048 // The x86 needs to save only a few registers, 
00049 // SPARC and MIPS needs to save 10 registers, 
00050 // the Snake needs 18,
00051 // and the RS6000 needs to save 75 (!)
00052 // For simplicity, I just take the maximum over all architectures.
00053 
00054 #define MachineStateSize 75 
00055 
00056 
00057 // Size of the thread's private execution stack.
00058 // WATCH OUT IF THIS ISN'T BIG ENOUGH!!!!!
00059 const int StackSize = (8 * 1024);       // in words
00060 
00061 
00062 // Thread state
00063 enum ThreadStatus { JUST_CREATED, RUNNING, READY, BLOCKED };
00064 
00065 
00066 // The following class defines a "thread control block" -- which
00067 // represents a single thread of execution.
00068 //
00069 //  Every thread has:
00070 //     an execution stack for activation records ("stackTop" and "stack")
00071 //     space to save CPU registers while not running ("machineState")
00072 //     a "status" (running/ready/blocked)
00073 //    
00074 //  Some threads also belong to a user address space; threads
00075 //  that only run in the kernel have a NULL address space.
00076 
00077 class Thread {
00078   private:
00079     // NOTE: DO NOT CHANGE the order of these first two members.
00080     // THEY MUST be in this position for SWITCH to work.
00081     int *stackTop;                       // the current stack pointer
00082     void *machineState[MachineStateSize];  // all registers except for stackTop
00083 
00084   public:
00085     Thread(char* debugName);            // initialize a Thread 
00086     ~Thread();                          // deallocate a Thread
00087                                         // NOTE -- thread being deleted
00088                                         // must not be running when delete 
00089                                         // is called
00090 
00091     // basic thread operations
00092 
00093     void Fork(VoidFunctionPtr func, void *arg); 
00094                                 // Make thread run (*func)(arg)
00095     void Yield();               // Relinquish the CPU if any 
00096                                 // other thread is runnable
00097     void Sleep(bool finishing); // Put the thread to sleep and 
00098                                 // relinquish the processor
00099     void Begin();               // Startup code for the thread  
00100     void Finish();              // The thread is done executing
00101     
00102     void CheckOverflow();       // Check if thread stack has overflowed
00103     void setStatus(ThreadStatus st) { status = st; }
00104     char* getName() { return (name); }
00105     void Print() { cout << name; }
00106     void SelfTest();            // test whether thread impl is working
00107 
00108   private:
00109     // some of the private data for this class is listed above
00110     
00111     int *stack;                 // Bottom of the stack 
00112                                 // NULL if this is the main thread
00113                                 // (If NULL, don't deallocate stack)
00114     ThreadStatus status;        // ready, running or blocked
00115     char* name;
00116 
00117     void StackAllocate(VoidFunctionPtr func, void *arg);
00118                                 // Allocate a stack for thread.
00119                                 // Used internally by Fork()
00120 
00121 // A thread running a user program actually has *two* sets of CPU registers -- 
00122 // one for its state while executing user code, one for its state 
00123 // while executing kernel code.
00124 
00125     int userRegisters[NumTotalRegs];    // user-level CPU register state
00126 
00127   public:
00128     void SaveUserState();               // save user-level register state
00129     void RestoreUserState();            // restore user-level register state
00130 
00131     AddrSpace *space;                   // User code this thread is running.
00132 };
00133 
00134 // external function, dummy routine whose sole job is to call Thread::Print
00135 extern void ThreadPrint(Thread *thread);         
00136 
00137 // Magical machine-dependent routines, defined in switch.s
00138 
00139 extern "C" {
00140 // First frame on thread execution stack; 
00141 //      call ThreadBegin
00142 //      call "func"
00143 //      (when func returns, if ever) call ThreadFinish()
00144 void ThreadRoot();
00145 
00146 // Stop running oldThread and start running newThread
00147 void SWITCH(Thread *oldThread, Thread *newThread);
00148 }
00149 
00150 #endif // THREAD_H

Généré le Sun Jan 15 00:45:46 2006 pour Système NachOS : par  doxygen 1.4.4