Main Page   Compound List   File List   Compound Members   File Members  

thread.h

Go to the documentation of this file.
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-1993 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 
00043 #ifdef USER_PROGRAM
00044 #include "machine.h"
00045 #include "addrspace.h"
00046 #endif
00047 
00048 // CPU register state to be saved on context switch.  
00049 // The SPARC and MIPS only need 10 registers, but the Snake needs 18.
00050 // For simplicity, this is just the max over all architectures.
00051 #define MachineStateSize 18 
00052 
00053 
00054 // Size of the thread's private execution stack.
00055 // WATCH OUT IF THIS ISN'T BIG ENOUGH!!!!!
00056 #define StackSize       (4 * 1024)      // in words
00057 
00058 
00059 // Thread state
00060 enum ThreadStatus { JUST_CREATED, RUNNING, READY, BLOCKED };
00061 
00062 // external function, dummy routine whose sole job is to call Thread::Print
00063 extern void ThreadPrint(int arg);        
00064 
00065 // The following class defines a "thread control block" -- which
00066 // represents a single thread of execution.
00067 //
00068 //  Every thread has:
00069 //     an execution stack for activation records ("stackTop" and "stack")
00070 //     space to save CPU registers while not running ("machineState")
00071 //     a "status" (running/ready/blocked)
00072 //    
00073 //  Some threads also belong to a user address space; threads
00074 //  that only run in the kernel have a NULL address space.
00075 
00076 class Thread {
00077   private:
00078     // NOTE: DO NOT CHANGE the order of these first two members.
00079     // THEY MUST be in this position for SWITCH to work.
00080     int* stackTop;                       // the current stack pointer
00081     int machineState[MachineStateSize];  // all registers except for stackTop
00082 
00083   public:
00084     Thread(char* debugName);            // initialize a Thread 
00085     ~Thread();                          // deallocate a Thread
00086                                         // NOTE -- thread being deleted
00087                                         // must not be running when delete 
00088                                         // is called
00089 
00090     // basic thread operations
00091 
00092     void Fork(VoidFunctionPtr func, int arg);   // Make thread run (*func)(arg)
00093     void Yield();                               // Relinquish the CPU if any 
00094                                                 // other thread is runnable
00095     void Sleep();                               // Put the thread to sleep and 
00096                                                 // relinquish the processor
00097     void Finish();                              // The thread is done executing
00098     
00099     void CheckOverflow();                       // Check if thread has 
00100                                                 // overflowed its stack
00101     void setStatus(ThreadStatus st) { status = st; }
00102     char* getName() { return (name); }
00103     void Print() { printf("%s, ", name); }
00104 
00105   private:
00106     // some of the private data for this class is listed above
00107     
00108     int* stack;                         // Bottom of the stack 
00109                                         // NULL if this is the main thread
00110                                         // (If NULL, don't deallocate stack)
00111     ThreadStatus status;                // ready, running or blocked
00112     char* name;
00113 
00114     void StackAllocate(VoidFunctionPtr func, int arg);
00115                                         // Allocate a stack for thread.
00116                                         // Used internally by Fork()
00117 
00118 #ifdef USER_PROGRAM
00119 // A thread running a user program actually has *two* sets of CPU registers -- 
00120 // one for its state while executing user code, one for its state 
00121 // while executing kernel code.
00122 
00123     int userRegisters[NumTotalRegs];    // user-level CPU register state
00124 
00125   public:
00126     void SaveUserState();               // save user-level register state
00127     void RestoreUserState();            // restore user-level register state
00128 
00129     AddrSpace *space;                   // User code this thread is running.
00130 #endif
00131 };
00132 
00133 // Magical machine-dependent routines, defined in switch.s
00134 
00135 extern "C" {
00136 // First frame on thread execution stack; 
00137 //      enable interrupts
00138 //      call "func"
00139 //      (when func returns, if ever) call ThreadFinish()
00140 void ThreadRoot();
00141 
00142 // Stop running oldThread and start running newThread
00143 void SWITCH(Thread *oldThread, Thread *newThread);
00144 }
00145 
00146 #endif // THREAD_H

Generated on Mon Feb 10 09:54:48 2003 for nachos by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002
The University of Southern California does not screen or control the content on this website and thus does not guarantee the accuracy, integrity, or quality of such content. All content on this website is provided by and is the sole responsibility of the person from which such content originated, and such content does not necessarily reflect the opinions of the University administration or the Board of Trustees