Make tests public. Rewrite most tests. Add tests.
[pintos-anon] / src / threads / thread.c
1 #include "threads/thread.h"
2 #include <debug.h>
3 #include <stddef.h>
4 #include <random.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include "threads/flags.h"
8 #include "threads/interrupt.h"
9 #include "threads/intr-stubs.h"
10 #include "threads/mmu.h"
11 #include "threads/palloc.h"
12 #include "threads/switch.h"
13 #include "threads/synch.h"
14 #ifdef USERPROG
15 #include "userprog/process.h"
16 #endif
17
18 /* Random value for struct thread's `magic' member.
19    Used to detect stack overflow.  See the big comment at the top
20    of thread.h for details. */
21 #define THREAD_MAGIC 0xcd6abf4b
22
23 /* List of processes in THREAD_READY state, that is, processes
24    that are ready to run but not actually running. */
25 static struct list ready_list;
26
27 /* Idle thread. */
28 static struct thread *idle_thread;
29
30 /* Initial thread, the thread running init.c:main(). */
31 static struct thread *initial_thread;
32
33 /* Lock used by allocate_tid(). */
34 static struct lock tid_lock;
35
36 /* Stack frame for kernel_thread(). */
37 struct kernel_thread_frame 
38   {
39     void *eip;                  /* Return address. */
40     thread_func *function;      /* Function to call. */
41     void *aux;                  /* Auxiliary data for function. */
42   };
43
44 /* Statistics. */
45 static long long idle_ticks;    /* # of timer ticks spent idle. */
46 static long long kernel_ticks;  /* # of timer ticks in kernel threads. */
47 static long long user_ticks;    /* # of timer ticks in user programs. */
48
49 /* Scheduling. */
50 #define TIME_SLICE 4            /* # of timer ticks to give each thread. */
51 static unsigned thread_ticks;   /* # of timer ticks since last yield. */
52
53 static void kernel_thread (thread_func *, void *aux);
54
55 static void idle (void *aux UNUSED);
56 static struct thread *running_thread (void);
57 static struct thread *next_thread_to_run (void);
58 static void init_thread (struct thread *, const char *name, int priority);
59 static bool is_thread (struct thread *) UNUSED;
60 static void *alloc_frame (struct thread *, size_t size);
61 static void schedule (void);
62 void schedule_tail (struct thread *prev);
63 static tid_t allocate_tid (void);
64
65 /* Initializes the threading system by transforming the code
66    that's currently running into a thread.  This can't work in
67    general and it is possible in this case only because loader.S
68    was careful to put the bottom of the stack at a page boundary.
69
70    Also initializes the run queue and the tid lock.
71
72    After calling this function, be sure to initialize the page
73    allocator before trying to create any threads with
74    thread_create(). */
75 void
76 thread_init (void) 
77 {
78   ASSERT (intr_get_level () == INTR_OFF);
79
80   lock_init (&tid_lock);
81   list_init (&ready_list);
82
83   /* Set up a thread structure for the running thread. */
84   initial_thread = running_thread ();
85   init_thread (initial_thread, "main", PRI_DEFAULT);
86   initial_thread->status = THREAD_RUNNING;
87   initial_thread->tid = allocate_tid ();
88 }
89
90 /* Starts preemptive thread scheduling by enabling interrupts.
91    Also creates the idle thread. */
92 void
93 thread_start (void) 
94 {
95   thread_create ("idle", PRI_MAX, idle, NULL);
96   intr_enable ();
97 }
98
99 /* Called by the timer interrupt handler at each timer tick. */
100 void
101 thread_tick (void) 
102 {
103   struct thread *t = thread_current ();
104
105   /* Update statistics. */
106   if (t == idle_thread)
107     idle_ticks++;
108 #ifdef USERPROG
109   else if (t->pagedir != NULL)
110     user_ticks++;
111 #endif
112   else
113     kernel_ticks++;
114
115   /* Enforce preemption. */
116   if (++thread_ticks >= TIME_SLICE)
117     intr_yield_on_return ();
118 }
119
120 /* Prints thread statistics. */
121 void
122 thread_print_stats (void) 
123 {
124   printf ("Thread: %lld idle ticks, %lld kernel ticks, %lld user ticks\n",
125           idle_ticks, kernel_ticks, user_ticks);
126 }
127
128 /* Creates a new kernel thread named NAME with the given initial
129    PRIORITY, which executes FUNCTION passing AUX as the argument,
130    and adds it to the ready queue.  Returns the thread identifier
131    for the new thread, or TID_ERROR if creation fails.
132
133    If thread_start() has been called, then the new thread may be
134    scheduled before thread_create() returns.  It could even exit
135    before thread_create() returns.  Contrariwise, the original
136    thread may run for any amount of time before the new thread is
137    scheduled.  Use a semaphore or some other form of
138    synchronization if you need to ensure ordering.
139
140    The code provided sets the new thread's `priority' member to
141    PRIORITY, but no actual priority scheduling is implemented.
142    Priority scheduling is the goal of Problem 1-3. */
143 tid_t
144 thread_create (const char *name, int priority,
145                thread_func *function, void *aux) 
146 {
147   struct thread *t;
148   struct kernel_thread_frame *kf;
149   struct switch_entry_frame *ef;
150   struct switch_threads_frame *sf;
151   tid_t tid;
152
153   ASSERT (function != NULL);
154
155   /* Allocate thread. */
156   t = palloc_get_page (PAL_ZERO);
157   if (t == NULL)
158     return TID_ERROR;
159
160   /* Initialize thread. */
161   init_thread (t, name, priority);
162   tid = t->tid = allocate_tid ();
163
164   /* Stack frame for kernel_thread(). */
165   kf = alloc_frame (t, sizeof *kf);
166   kf->eip = NULL;
167   kf->function = function;
168   kf->aux = aux;
169
170   /* Stack frame for switch_entry(). */
171   ef = alloc_frame (t, sizeof *ef);
172   ef->eip = (void (*) (void)) kernel_thread;
173
174   /* Stack frame for switch_threads(). */
175   sf = alloc_frame (t, sizeof *sf);
176   sf->eip = switch_entry;
177
178   /* Add to run queue. */
179   thread_unblock (t);
180
181   return tid;
182 }
183
184 /* Puts the current thread to sleep.  It will not be scheduled
185    again until awoken by thread_unblock().
186
187    This function must be called with interrupts turned off.  It
188    is usually a better idea to use one of the synchronization
189    primitives in synch.h. */
190 void
191 thread_block (void) 
192 {
193   ASSERT (!intr_context ());
194   ASSERT (intr_get_level () == INTR_OFF);
195
196   thread_current ()->status = THREAD_BLOCKED;
197   schedule ();
198 }
199
200 /* Transitions a blocked thread T to the ready-to-run state.
201    This is an error if T is not blocked.  (Use thread_yield() to
202    make the running thread ready.) */
203 void
204 thread_unblock (struct thread *t) 
205 {
206   enum intr_level old_level;
207
208   ASSERT (is_thread (t));
209
210   old_level = intr_disable ();
211   ASSERT (t->status == THREAD_BLOCKED);
212   list_push_back (&ready_list, &t->elem);
213   t->status = THREAD_READY;
214   intr_set_level (old_level);
215 }
216
217 /* Returns the name of the running thread. */
218 const char *
219 thread_name (void) 
220 {
221   return thread_current ()->name;
222 }
223
224 /* Returns the running thread.
225    This is running_thread() plus a couple of sanity checks.
226    See the big comment at the top of thread.h for details. */
227 struct thread *
228 thread_current (void) 
229 {
230   struct thread *t = running_thread ();
231   
232   /* Make sure T is really a thread.
233      If either of these assertions fire, then your thread may
234      have overflowed its stack.  Each thread has less than 4 kB
235      of stack, so a few big automatic arrays or moderate
236      recursion can cause stack overflow. */
237   ASSERT (is_thread (t));
238   ASSERT (t->status == THREAD_RUNNING);
239
240   return t;
241 }
242
243 /* Returns the running thread's tid. */
244 tid_t
245 thread_tid (void) 
246 {
247   return thread_current ()->tid;
248 }
249
250 /* Deschedules the current thread and destroys it.  Never
251    returns to the caller. */
252 void
253 thread_exit (void) 
254 {
255   ASSERT (!intr_context ());
256
257 #ifdef USERPROG
258   process_exit ();
259 #endif
260
261   /* Just set our status to dying and schedule another process.
262      We will be destroyed during the call to schedule_tail(). */
263   intr_disable ();
264   thread_current ()->status = THREAD_DYING;
265   schedule ();
266   NOT_REACHED ();
267 }
268
269 /* Yields the CPU.  The current thread is not put to sleep and
270    may be scheduled again immediately at the scheduler's whim. */
271 void
272 thread_yield (void) 
273 {
274   struct thread *cur = thread_current ();
275   enum intr_level old_level;
276   
277   ASSERT (!intr_context ());
278
279   old_level = intr_disable ();
280   list_push_back (&ready_list, &cur->elem);
281   cur->status = THREAD_READY;
282   schedule ();
283   intr_set_level (old_level);
284 }
285
286 /* Sets the current thread's priority to NEW_PRIORITY. */
287 void
288 thread_set_priority (int new_priority) 
289 {
290   thread_current ()->priority = new_priority;
291 }
292
293 /* Returns the current thread's priority. */
294 int
295 thread_get_priority (void) 
296 {
297   return thread_current ()->priority;
298 }
299
300 /* Sets the current thread's nice value to NICE. */
301 void
302 thread_set_nice (int nice UNUSED) 
303 {
304   /* Not yet implemented. */
305 }
306
307 /* Returns the current thread's nice value. */
308 int
309 thread_get_nice (void) 
310 {
311   /* Not yet implemented. */
312   return 0;
313 }
314
315 /* Returns 100 times the system load average. */
316 int
317 thread_get_load_avg (void) 
318 {
319   /* Not yet implemented. */
320   return 0;
321 }
322
323 /* Returns 100 times the current thread's recent_cpu value. */
324 int
325 thread_get_recent_cpu (void) 
326 {
327   /* Not yet implemented. */
328   return 0;
329 }
330 \f
331 /* Idle thread.  Executes when no other thread is ready to run. */
332 static void
333 idle (void *aux UNUSED) 
334 {
335   idle_thread = thread_current ();
336
337   for (;;) 
338     {
339       /* Let someone else run. */
340       intr_disable ();
341       thread_block ();
342
343       /* Re-enable interrupts and wait for the next one.
344
345          The `sti' instruction disables interrupts until the
346          completion of the next instruction, so these two
347          instructions are executed atomically.  This atomicity is
348          important; otherwise, an interrupt could be handled
349          between re-enabling interrupts and waiting for the next
350          one to occur, wasting as much as one clock tick worth of
351          time.
352
353          See [IA32-v2a] "HLT", [IA32-v2b] "STI", and [IA32-v3] 7.7. */
354       asm ("sti; hlt");
355     }
356 }
357
358 /* Function used as the basis for a kernel thread. */
359 static void
360 kernel_thread (thread_func *function, void *aux) 
361 {
362   ASSERT (function != NULL);
363
364   intr_enable ();       /* The scheduler runs with interrupts off. */
365   function (aux);       /* Execute the thread function. */
366   thread_exit ();       /* If function() returns, kill the thread. */
367 }
368 \f
369 /* Returns the running thread. */
370 struct thread *
371 running_thread (void) 
372 {
373   uint32_t *esp;
374
375   /* Copy the CPU's stack pointer into `esp', and then round that
376      down to the start of a page.  Because `struct thread' is
377      always at the beginning of a page and the stack pointer is
378      somewhere in the middle, this locates the curent thread. */
379   asm ("mov %0, %%esp" : "=g" (esp));
380   return pg_round_down (esp);
381 }
382
383 /* Returns true if T appears to point to a valid thread. */
384 static bool
385 is_thread (struct thread *t)
386 {
387   return t != NULL && t->magic == THREAD_MAGIC;
388 }
389
390 /* Does basic initialization of T as a blocked thread named
391    NAME. */
392 static void
393 init_thread (struct thread *t, const char *name, int priority)
394 {
395   ASSERT (t != NULL);
396   ASSERT (PRI_MIN <= priority && priority <= PRI_MAX);
397   ASSERT (name != NULL);
398
399   memset (t, 0, sizeof *t);
400   t->status = THREAD_BLOCKED;
401   strlcpy (t->name, name, sizeof t->name);
402   t->stack = (uint8_t *) t + PGSIZE;
403   t->priority = priority;
404   t->magic = THREAD_MAGIC;
405 }
406
407 /* Allocates a SIZE-byte frame at the top of thread T's stack and
408    returns a pointer to the frame's base. */
409 static void *
410 alloc_frame (struct thread *t, size_t size) 
411 {
412   /* Stack data is always allocated in word-size units. */
413   ASSERT (is_thread (t));
414   ASSERT (size % sizeof (uint32_t) == 0);
415
416   t->stack -= size;
417   return t->stack;
418 }
419
420 /* Chooses and returns the next thread to be scheduled.  Should
421    return a thread from the run queue, unless the run queue is
422    empty.  (If the running thread can continue running, then it
423    will be in the run queue.)  If the run queue is empty, return
424    idle_thread. */
425 static struct thread *
426 next_thread_to_run (void) 
427 {
428   if (list_empty (&ready_list))
429     return idle_thread;
430   else
431     return list_entry (list_pop_front (&ready_list), struct thread, elem);
432 }
433
434 /* Completes a thread switch by activating the new thread's page
435    tables, and, if the previous thread is dying, destroying it.
436
437    At this function's invocation, we just switched from thread
438    PREV, the new thread is already running, and interrupts are
439    still disabled.  This function is normally invoked by
440    thread_schedule() as its final action before returning, but
441    the first time a thread is scheduled it is called by
442    switch_entry() (see switch.S).
443
444    It's not safe to call printf() until the thread switch is
445    complete.  In practice that means that printf()s should be
446    added at the end of the function.
447
448    After this function and its caller returns, the thread switch
449    is complete. */
450 void
451 schedule_tail (struct thread *prev) 
452 {
453   struct thread *cur = running_thread ();
454   
455   ASSERT (intr_get_level () == INTR_OFF);
456
457   /* Mark us as running. */
458   cur->status = THREAD_RUNNING;
459
460   /* Start new time slice. */
461   thread_ticks = 0;
462
463 #ifdef USERPROG
464   /* Activate the new address space. */
465   process_activate ();
466 #endif
467
468   /* If the thread we switched from is dying, destroy its struct
469      thread.  This must happen late so that thread_exit() doesn't
470      pull out the rug under itself. */
471   if (prev != NULL && prev->status == THREAD_DYING) 
472     {
473       ASSERT (prev != cur);
474       if (prev != initial_thread)
475         palloc_free_page (prev);
476     }
477 }
478
479 /* Schedules a new process.  At entry, interrupts must be off and
480    the running process's state must have been changed from
481    running to some other state.  This function finds another
482    thread to run and switches to it.
483
484    It's not safe to call printf() until schedule_tail() has
485    completed. */
486 static void
487 schedule (void) 
488 {
489   struct thread *cur = running_thread ();
490   struct thread *next = next_thread_to_run ();
491   struct thread *prev = NULL;
492
493   ASSERT (intr_get_level () == INTR_OFF);
494   ASSERT (cur->status != THREAD_RUNNING);
495   ASSERT (is_thread (next));
496
497   if (cur != next)
498     prev = switch_threads (cur, next);
499   schedule_tail (prev); 
500 }
501
502 /* Returns a tid to use for a new thread. */
503 static tid_t
504 allocate_tid (void) 
505 {
506   static tid_t next_tid = 1;
507   tid_t tid;
508
509   lock_acquire (&tid_lock);
510   tid = next_tid++;
511   lock_release (&tid_lock);
512
513   return tid;
514 }
515 \f
516 /* Offset of `stack' member within `struct thread'.
517    Used by switch.S, which can't figure it out on its own. */
518 uint32_t thread_stack_ofs = offsetof (struct thread, stack);