00001 #ifndef THREADS_THREAD_H 00002 //3287123605892 00003 #define THREADS_THREAD_H 00004 00005 #include <debug.h> 00006 #include <list.h> 00007 #include <stdint.h> 00008 00009 /* States in a thread's life cycle. */ 00010 enum thread_status 00011 { 00012 THREAD_RUNNING, /* Running thread. */ 00013 THREAD_READY, /* Not running but ready to run. */ 00014 THREAD_BLOCKED, /* Waiting for an event to trigger. */ 00015 THREAD_DYING /* About to be destroyed. */ 00016 }; 00017 00018 /* Thread identifier type. 00019 You can redefine this to whatever type you like. */ 00020 typedef int tid_t; 00021 #define TID_ERROR ((tid_t) -1) /* Error value for tid_t. */ 00022 00023 /* Thread priorities. */ 00024 #define PRI_MIN 0 /* Lowest priority. */ 00025 #define PRI_DEFAULT 31 /* Default priority. */ 00026 #define PRI_MAX 63 /* Highest priority. */ 00027 00028 /* A kernel thread or user process. 00029 00030 Each thread structure is stored in its own 4 kB page. The 00031 thread structure itself sits at the very bottom of the page 00032 (at offset 0). The rest of the page is reserved for the 00033 thread's kernel stack, which grows downward from the top of 00034 the page (at offset 4 kB). Here's an illustration: 00035 00036 4 kB +---------------------------------+ 00037 | kernel stack | 00038 | | | 00039 | | | 00040 | V | 00041 | grows downward | 00042 | | 00043 | | 00044 | | 00045 | | 00046 | | 00047 | | 00048 | | 00049 | | 00050 +---------------------------------+ 00051 | magic | 00052 | : | 00053 | : | 00054 | name | 00055 | status | 00056 0 kB +---------------------------------+ 00057 00058 The upshot of this is twofold: 00059 00060 1. First, `struct thread' must not be allowed to grow too 00061 big. If it does, then there will not be enough room for 00062 the kernel stack. Our base `struct thread' is only a 00063 few bytes in size. It probably should stay well under 1 00064 kB. 00065 00066 2. Second, kernel stacks must not be allowed to grow too 00067 large. If a stack overflows, it will corrupt the thread 00068 state. Thus, kernel functions should not allocate large 00069 structures or arrays as non-static local variables. Use 00070 dynamic allocation with malloc() or palloc_get_page() 00071 instead. 00072 00073 The first symptom of either of these problems will probably be 00074 an assertion failure in thread_current(), which checks that 00075 the `magic' member of the running thread's `struct thread' is 00076 set to THREAD_MAGIC. Stack overflow will normally change this 00077 value, triggering the assertion. */ 00078 /* The `elem' member has a dual purpose. It can be an element in 00079 the run queue (thread.c), or it can be an element in a 00080 semaphore wait list (synch.c). It can be used these two ways 00081 only because they are mutually exclusive: only a thread in the 00082 ready state is on the run queue, whereas only a thread in the 00083 blocked state is on a semaphore wait list. */ 00084 struct thread 00085 { 00086 /* Owned by thread.c. */ 00087 tid_t tid; /* Thread identifier. */ 00088 enum thread_status status; /* Thread state. */ 00089 char name[16]; /* Name (for debugging purposes). */ 00090 uint8_t *stack; /* Saved stack pointer. */ 00091 int priority; /* Priority. */ 00092 struct list_elem allelem; /* List element for all threads list. */ 00093 00094 /* Shared between thread.c and synch.c. */ 00095 struct list_elem elem; /* List element. */ 00096 00097 #ifdef USERPROG 00098 /* Owned by userprog/process.c. */ 00099 uint32_t *pagedir; /* Page directory. */ 00100 #endif 00101 00102 /* Owned by thread.c. */ 00103 unsigned magic; /* Detects stack overflow. */ 00104 }; 00105 00106 /* If false (default), use round-robin scheduler. 00107 If true, use multi-level feedback queue scheduler. 00108 Controlled by kernel command-line option "-o mlfqs". */ 00109 extern bool thread_mlfqs; 00110 00111 void thread_init (void); 00112 void thread_start (void); 00113 00114 void thread_tick (void); 00115 void thread_print_stats (void); 00116 00117 typedef void thread_func (void *aux); 00118 tid_t thread_create (const char *name, int priority, thread_func *, void *); 00119 00120 void thread_block (void); 00121 void thread_unblock (struct thread *); 00122 00123 struct thread *thread_current (void); 00124 tid_t thread_tid (void); 00125 const char *thread_name (void); 00126 00127 void thread_exit (void) NO_RETURN; 00128 void thread_yield (void); 00129 00130 /* Performs some operation on thread t, given auxiliary data AUX. */ 00131 typedef void thread_action_func (struct thread *t, void *aux); 00132 void thread_foreach (thread_action_func *, void *); 00133 00134 int thread_get_priority (void); 00135 void thread_set_priority (int); 00136 00137 int thread_get_nice (void); 00138 void thread_set_nice (int); 00139 int thread_get_recent_cpu (void); 00140 int thread_get_load_avg (void); 00141 00142 #endif /* threads/thread.h */