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