diff options
| author | manuel <manuel@mausz.at> | 2012-03-26 12:54:45 +0200 |
|---|---|---|
| committer | manuel <manuel@mausz.at> | 2012-03-26 12:54:45 +0200 |
| commit | b5f0874cd96ee2a62aabc645b9626c2749cb6a01 (patch) | |
| tree | 1262e4bbe0634de6650be130c36e0538240f4cbf /pintos-progos/threads/thread.h | |
| download | progos-b5f0874cd96ee2a62aabc645b9626c2749cb6a01.tar.gz progos-b5f0874cd96ee2a62aabc645b9626c2749cb6a01.tar.bz2 progos-b5f0874cd96ee2a62aabc645b9626c2749cb6a01.zip | |
initial pintos checkin
Diffstat (limited to 'pintos-progos/threads/thread.h')
| -rw-r--r-- | pintos-progos/threads/thread.h | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/pintos-progos/threads/thread.h b/pintos-progos/threads/thread.h new file mode 100644 index 0000000..eebf42c --- /dev/null +++ b/pintos-progos/threads/thread.h | |||
| @@ -0,0 +1,144 @@ | |||
| 1 | #ifndef THREADS_THREAD_H | ||
| 2 | #define THREADS_THREAD_H | ||
| 3 | |||
| 4 | #include <debug.h> | ||
| 5 | #include <list.h> | ||
| 6 | #include <stdint.h> | ||
| 7 | #include "threads/synch.h" | ||
| 8 | |||
| 9 | /* States in a thread's life cycle. */ | ||
| 10 | enum thread_status | ||
| 11 | { | ||
| 12 | THREAD_RUNNING, /* Running thread. */ | ||
| 13 | THREAD_READY, /* Not running but ready to run. */ | ||
| 14 | THREAD_BLOCKED, /* Waiting for an event to trigger. */ | ||
| 15 | THREAD_DYING /* About to be destroyed. */ | ||
| 16 | }; | ||
| 17 | |||
| 18 | /* Thread identifier type. | ||
| 19 | You can redefine this to whatever type you like. */ | ||
| 20 | typedef int tid_t; | ||
| 21 | #define TID_ERROR ((tid_t) -1) /* Error value for tid_t. */ | ||
| 22 | |||
| 23 | /* Thread priorities. */ | ||
| 24 | #define PRI_MIN 0 /* Lowest priority. */ | ||
| 25 | #define PRI_DEFAULT 31 /* Default priority. */ | ||
| 26 | #define PRI_MAX 63 /* Highest priority. */ | ||
| 27 | |||
| 28 | /* A kernel thread or user process. | ||
| 29 | |||
| 30 | Each thread structure is stored in its own 4 kB page. The | ||
| 31 | thread structure itself sits at the very bottom of the page | ||
| 32 | (at offset 0). The rest of the page is reserved for the | ||
| 33 | thread's kernel stack, which grows downward from the top of | ||
| 34 | the page (at offset 4 kB). Here's an illustration: | ||
| 35 | |||
| 36 | 4 kB +---------------------------------+ | ||
| 37 | | kernel stack | | ||
| 38 | | | | | ||
| 39 | | | | | ||
| 40 | | V | | ||
| 41 | | grows downward | | ||
| 42 | | | | ||
| 43 | | | | ||
| 44 | | | | ||
| 45 | | | | ||
| 46 | | | | ||
| 47 | | | | ||
| 48 | | | | ||
| 49 | | | | ||
| 50 | +---------------------------------+ | ||
| 51 | | magic | | ||
| 52 | | : | | ||
| 53 | | : | | ||
| 54 | | name | | ||
| 55 | | status | | ||
| 56 | 0 kB +---------------------------------+ | ||
| 57 | |||
| 58 | The upshot of this is twofold: | ||
| 59 | |||
| 60 | 1. First, `struct thread' must not be allowed to grow too | ||
| 61 | big. If it does, then there will not be enough room for | ||
| 62 | the kernel stack. Our base `struct thread' is only a | ||
| 63 | few bytes in size. It probably should stay well under 1 | ||
| 64 | kB. | ||
| 65 | |||
| 66 | 2. Second, kernel stacks must not be allowed to grow too | ||
| 67 | large. If a stack overflows, it will corrupt the thread | ||
| 68 | state. Thus, kernel functions should not allocate large | ||
| 69 | structures or arrays as non-static local variables. Use | ||
| 70 | dynamic allocation with malloc() or palloc_get_page() | ||
| 71 | instead. | ||
| 72 | |||
| 73 | The first symptom of either of these problems will probably be | ||
| 74 | an assertion failure in thread_current(), which checks that | ||
| 75 | the `magic' member of the running thread's `struct thread' is | ||
| 76 | set to THREAD_MAGIC. Stack overflow will normally change this | ||
| 77 | value, triggering the assertion. */ | ||
| 78 | /* The `elem' member has a dual purpose. It can be an element in | ||
| 79 | the run queue (thread.c), or it can be an element in a | ||
| 80 | semaphore wait list (synch.c). It can be used these two ways | ||
| 81 | only because they are mutually exclusive: only a thread in the | ||
| 82 | ready state is on the run queue, whereas only a thread in the | ||
| 83 | blocked state is on a semaphore wait list. */ | ||
| 84 | struct thread | ||
| 85 | { | ||
| 86 | /* Owned by thread.c. */ | ||
| 87 | tid_t tid; /* Thread identifier. */ | ||
| 88 | enum thread_status status; /* Thread state. */ | ||
| 89 | char name[16]; /* Name (for debugging purposes). */ | ||
| 90 | uint8_t *stack; /* Saved stack pointer. */ | ||
| 91 | int priority; /* Priority. */ | ||
| 92 | struct list_elem allelem; /* List element for all threads list. */ | ||
| 93 | |||
| 94 | /* Shared between thread.c and synch.c. */ | ||
| 95 | struct list_elem elem; /* List element. */ | ||
| 96 | |||
| 97 | #ifdef USERPROG | ||
| 98 | /* Owned by userprog/process.c */ | ||
| 99 | struct process* process; /* Process Structure */ | ||
| 100 | struct list children; /* Threads can hold processes, but not vice versa */ | ||
| 101 | uint32_t *pagedir; /* Page directory. */ | ||
| 102 | #endif | ||
| 103 | |||
| 104 | /* Owned by thread.c. */ | ||
| 105 | unsigned magic; /* Detects stack overflow. */ | ||
| 106 | }; | ||
| 107 | |||
| 108 | /* If false (default), use round-robin scheduler. | ||
| 109 | If true, use multi-level feedback queue scheduler. | ||
| 110 | Controlled by kernel command-line option "-o mlfqs". */ | ||
| 111 | extern bool thread_mlfqs; | ||
| 112 | |||
| 113 | void thread_init (void); | ||
| 114 | void thread_start (void); | ||
| 115 | |||
| 116 | void thread_tick (void); | ||
| 117 | void thread_print_stats (void); | ||
| 118 | |||
| 119 | typedef void thread_func (void *aux); | ||
| 120 | tid_t thread_create (const char *name, int priority, thread_func *, void *); | ||
| 121 | |||
| 122 | void thread_block (void); | ||
| 123 | void thread_unblock (struct thread *); | ||
| 124 | |||
| 125 | struct thread *thread_current (void); | ||
| 126 | tid_t thread_tid (void); | ||
| 127 | const char *thread_name (void); | ||
| 128 | |||
| 129 | void thread_exit (void) NO_RETURN; | ||
| 130 | void thread_yield (void); | ||
| 131 | |||
| 132 | /* Performs some operation on thread t, given auxiliary data AUX. */ | ||
| 133 | typedef void thread_action_func (struct thread *t, void *aux); | ||
| 134 | void thread_foreach (thread_action_func *, void *); | ||
| 135 | |||
| 136 | int thread_get_priority (void); | ||
| 137 | void thread_set_priority (int); | ||
| 138 | |||
| 139 | int thread_get_nice (void); | ||
| 140 | void thread_set_nice (int); | ||
| 141 | int thread_get_recent_cpu (void); | ||
| 142 | int thread_get_load_avg (void); | ||
| 143 | |||
| 144 | #endif /* threads/thread.h */ | ||
