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