00001 /* 00002 * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009 00003 * The President and Fellows of Harvard College. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the University nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 */ 00029 00030 #ifndef _THREAD_H_ 00031 #define _THREAD_H_ 00032 00033 /* 00034 * Definition of a thread. 00035 * 00036 * Note: curthread is defined by <current.h>. 00037 */ 00038 00039 #include <array.h> 00040 #include <spinlock.h> 00041 #include <threadlist.h> 00042 00043 struct cpu; 00044 00045 /* get machine-dependent defs */ 00046 #include <machine/thread.h> 00047 00048 00049 /* Size of kernel stacks; must be power of 2 */ 00050 #define STACK_SIZE 4096 00051 00052 /* Mask for extracting the stack base address of a kernel stack pointer */ 00053 #define STACK_MASK (~(vaddr_t)(STACK_SIZE-1)) 00054 00055 /* Macro to test if two addresses are on the same kernel stack */ 00056 #define SAME_STACK(p1, p2) (((p1) & STACK_MASK) == ((p2) & STACK_MASK)) 00057 00058 00059 /* States a thread can be in. */ 00060 typedef enum { 00061 S_RUN, /* running */ 00062 S_READY, /* ready to run */ 00063 S_SLEEP, /* sleeping */ 00064 S_ZOMBIE, /* zombie; exited but not yet deleted */ 00065 } threadstate_t; 00066 00067 /* Thread structure. */ 00068 struct thread { 00069 /* 00070 * These go up front so they're easy to get to even if the 00071 * debugger is messed up. 00072 */ 00073 char *t_name; /* Name of this thread */ 00074 const char *t_wchan_name; /* Name of wait channel, if sleeping */ 00075 threadstate_t t_state; /* State this thread is in */ 00076 00077 /* 00078 * Thread subsystem internal fields. 00079 */ 00080 struct thread_machdep t_machdep; /* Any machine-dependent goo */ 00081 struct threadlistnode t_listnode; /* Link for run/sleep/zombie lists */ 00082 void *t_stack; /* Kernel-level stack */ 00083 struct switchframe *t_context; /* Saved register context (on stack) */ 00084 struct cpu *t_cpu; /* CPU thread runs on */ 00085 struct proc *t_proc; /* Process thread belongs to */ 00086 00087 /* 00088 * Interrupt state fields. 00089 * 00090 * t_in_interrupt is true if current execution is in an 00091 * interrupt handler, which means the thread's normal context 00092 * of execution is stopped somewhere in the middle of doing 00093 * something else. This makes assorted operations unsafe. 00094 * 00095 * See notes in spinlock.c regarding t_curspl and t_iplhigh_count. 00096 * 00097 * Exercise for the student: why is this material per-thread 00098 * rather than per-cpu or global? 00099 */ 00100 bool t_in_interrupt; /* Are we in an interrupt? */ 00101 int t_curspl; /* Current spl*() state */ 00102 int t_iplhigh_count; /* # of times IPL has been raised */ 00103 00104 /* 00105 * Public fields 00106 */ 00107 00108 /* add more here as needed */ 00109 }; 00110 00111 /* 00112 * Array of threads. 00113 */ 00114 #ifndef THREADINLINE 00115 #define THREADINLINE INLINE 00116 #endif 00117 00118 DECLARRAY(thread); 00119 DEFARRAY(thread, THREADINLINE); 00120 00121 /* Call once during system startup to allocate data structures. */ 00122 void thread_bootstrap(void); 00123 00124 /* Call late in system startup to get secondary CPUs running. */ 00125 void thread_start_cpus(void); 00126 00127 /* Call during panic to stop other threads in their tracks */ 00128 void thread_panic(void); 00129 00130 /* Call during system shutdown to offline other CPUs. */ 00131 void thread_shutdown(void); 00132 00133 /* 00134 * Make a new thread, which will start executing at "func". The thread 00135 * will belong to the process "proc", or to the current thread's 00136 * process if "proc" is null. The "data" arguments (one pointer, one 00137 * number) are passed to the function. The current thread is used as a 00138 * prototype for creating the new one. Returns an error code. The 00139 * thread structure for the new thread is not returned; it is not in 00140 * general safe to refer to it as the new thread may exit and 00141 * disappear at any time without notice. 00142 */ 00143 int thread_fork(const char *name, struct proc *proc, 00144 void (*func)(void *, unsigned long), 00145 void *data1, unsigned long data2); 00146 00147 /* 00148 * Cause the current thread to exit. 00149 * Interrupts need not be disabled. 00150 */ 00151 void thread_exit(void); 00152 00153 /* 00154 * Cause the current thread to yield to the next runnable thread, but 00155 * itself stay runnable. 00156 * Interrupts need not be disabled. 00157 */ 00158 void thread_yield(void); 00159 00160 /* 00161 * Reshuffle the run queue. Called from the timer interrupt. 00162 */ 00163 void schedule(void); 00164 00165 /* 00166 * Potentially migrate ready threads to other CPUs. Called from the 00167 * timer interrupt. 00168 */ 00169 void thread_consider_migration(void); 00170 00171 00172 #endif /* _THREAD_H_ */