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