thread: Properly protect 'all_list' around insertion.
[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   enum intr_level old_level;
175
176   ASSERT (function != NULL);
177
178   /* Allocate thread. */
179   t = palloc_get_page (PAL_ZERO);
180   if (t == NULL)
181     return TID_ERROR;
182
183   /* Initialize thread. */
184   init_thread (t, name, priority);
185   tid = t->tid = allocate_tid ();
186
187   /* Prepare thread for first run by initializing its stack.
188      Do this atomically so intermediate values for the 'stack' 
189      member cannot be observed. */
190   old_level = intr_disable ();
191
192   /* Stack frame for kernel_thread(). */
193   kf = alloc_frame (t, sizeof *kf);
194   kf->eip = NULL;
195   kf->function = function;
196   kf->aux = aux;
197
198   /* Stack frame for switch_entry(). */
199   ef = alloc_frame (t, sizeof *ef);
200   ef->eip = (void (*) (void)) kernel_thread;
201
202   /* Stack frame for switch_threads(). */
203   sf = alloc_frame (t, sizeof *sf);
204   sf->eip = switch_entry;
205   sf->ebp = 0;
206
207   intr_set_level (old_level);
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
235    This function does not preempt the running thread.  This can
236    be important: if the caller had disabled interrupts itself,
237    it may expect that it can atomically unblock a thread and
238    update other data. */
239 void
240 thread_unblock (struct thread *t) 
241 {
242   enum intr_level old_level;
243
244   ASSERT (is_thread (t));
245
246   old_level = intr_disable ();
247   ASSERT (t->status == THREAD_BLOCKED);
248   list_push_back (&ready_list, &t->elem);
249   t->status = THREAD_READY;
250   intr_set_level (old_level);
251 }
252
253 /* Returns the name of the running thread. */
254 const char *
255 thread_name (void) 
256 {
257   return thread_current ()->name;
258 }
259
260 /* Returns the running thread.
261    This is running_thread() plus a couple of sanity checks.
262    See the big comment at the top of thread.h for details. */
263 struct thread *
264 thread_current (void) 
265 {
266   struct thread *t = running_thread ();
267   
268   /* Make sure T is really a thread.
269      If either of these assertions fire, then your thread may
270      have overflowed its stack.  Each thread has less than 4 kB
271      of stack, so a few big automatic arrays or moderate
272      recursion can cause stack overflow. */
273   ASSERT (is_thread (t));
274   ASSERT (t->status == THREAD_RUNNING);
275
276   return t;
277 }
278
279 /* Returns the running thread's tid. */
280 tid_t
281 thread_tid (void) 
282 {
283   return thread_current ()->tid;
284 }
285
286 /* Deschedules the current thread and destroys it.  Never
287    returns to the caller. */
288 void
289 thread_exit (void) 
290 {
291   ASSERT (!intr_context ());
292
293 #ifdef USERPROG
294   process_exit ();
295 #endif
296
297   /* Remove thread from all threads list, set our status to dying,
298      and schedule another process.  That process will destroy us
299      when it calls thread_schedule_tail(). */
300   intr_disable ();
301   list_remove (&thread_current()->allelem);
302   thread_current ()->status = THREAD_DYING;
303   schedule ();
304   NOT_REACHED ();
305 }
306
307 /* Yields the CPU.  The current thread is not put to sleep and
308    may be scheduled again immediately at the scheduler's whim. */
309 void
310 thread_yield (void) 
311 {
312   struct thread *cur = thread_current ();
313   enum intr_level old_level;
314   
315   ASSERT (!intr_context ());
316
317   old_level = intr_disable ();
318   if (cur != idle_thread) 
319     list_push_back (&ready_list, &cur->elem);
320   cur->status = THREAD_READY;
321   schedule ();
322   intr_set_level (old_level);
323 }
324
325 /* Invoke function 'func' on all threads, passing along 'aux'.
326    This function must be called with interrupts off. */
327 void
328 thread_foreach (thread_action_func *func, void *aux)
329 {
330   struct list_elem *e;
331
332   ASSERT (intr_get_level () == INTR_OFF);
333
334   for (e = list_begin (&all_list); e != list_end (&all_list);
335        e = list_next (e))
336     {
337       struct thread *t = list_entry (e, struct thread, allelem);
338       func (t, aux);
339     }
340 }
341
342 /* Sets the current thread's priority to NEW_PRIORITY. */
343 void
344 thread_set_priority (int new_priority) 
345 {
346   thread_current ()->priority = new_priority;
347 }
348
349 /* Returns the current thread's priority. */
350 int
351 thread_get_priority (void) 
352 {
353   return thread_current ()->priority;
354 }
355
356 /* Sets the current thread's nice value to NICE. */
357 void
358 thread_set_nice (int nice UNUSED) 
359 {
360   /* Not yet implemented. */
361 }
362
363 /* Returns the current thread's nice value. */
364 int
365 thread_get_nice (void) 
366 {
367   /* Not yet implemented. */
368   return 0;
369 }
370
371 /* Returns 100 times the system load average. */
372 int
373 thread_get_load_avg (void) 
374 {
375   /* Not yet implemented. */
376   return 0;
377 }
378
379 /* Returns 100 times the current thread's recent_cpu value. */
380 int
381 thread_get_recent_cpu (void) 
382 {
383   /* Not yet implemented. */
384   return 0;
385 }
386 \f
387 /* Idle thread.  Executes when no other thread is ready to run.
388
389    The idle thread is initially put on the ready list by
390    thread_start().  It will be scheduled once initially, at which
391    point it initializes idle_thread, "up"s the semaphore passed
392    to it to enable thread_start() to continue, and immediately
393    blocks.  After that, the idle thread never appears in the
394    ready list.  It is returned by next_thread_to_run() as a
395    special case when the ready list is empty. */
396 static void
397 idle (void *idle_started_ UNUSED) 
398 {
399   struct semaphore *idle_started = idle_started_;
400   idle_thread = thread_current ();
401   sema_up (idle_started);
402
403   for (;;) 
404     {
405       /* Let someone else run. */
406       intr_disable ();
407       thread_block ();
408
409       /* Re-enable interrupts and wait for the next one.
410
411          The `sti' instruction disables interrupts until the
412          completion of the next instruction, so these two
413          instructions are executed atomically.  This atomicity is
414          important; otherwise, an interrupt could be handled
415          between re-enabling interrupts and waiting for the next
416          one to occur, wasting as much as one clock tick worth of
417          time.
418
419          See [IA32-v2a] "HLT", [IA32-v2b] "STI", and [IA32-v3a]
420          7.11.1 "HLT Instruction". */
421       asm volatile ("sti; hlt" : : : "memory");
422     }
423 }
424
425 /* Function used as the basis for a kernel thread. */
426 static void
427 kernel_thread (thread_func *function, void *aux) 
428 {
429   ASSERT (function != NULL);
430
431   intr_enable ();       /* The scheduler runs with interrupts off. */
432   function (aux);       /* Execute the thread function. */
433   thread_exit ();       /* If function() returns, kill the thread. */
434 }
435 \f
436 /* Returns the running thread. */
437 struct thread *
438 running_thread (void) 
439 {
440   uint32_t *esp;
441
442   /* Copy the CPU's stack pointer into `esp', and then round that
443      down to the start of a page.  Because `struct thread' is
444      always at the beginning of a page and the stack pointer is
445      somewhere in the middle, this locates the curent thread. */
446   asm ("mov %%esp, %0" : "=g" (esp));
447   return pg_round_down (esp);
448 }
449
450 /* Returns true if T appears to point to a valid thread. */
451 static bool
452 is_thread (struct thread *t)
453 {
454   return t != NULL && t->magic == THREAD_MAGIC;
455 }
456
457 /* Does basic initialization of T as a blocked thread named
458    NAME. */
459 static void
460 init_thread (struct thread *t, const char *name, int priority)
461 {
462   enum intr_level old_level;
463
464   ASSERT (t != NULL);
465   ASSERT (PRI_MIN <= priority && priority <= PRI_MAX);
466   ASSERT (name != NULL);
467
468   memset (t, 0, sizeof *t);
469   t->status = THREAD_BLOCKED;
470   strlcpy (t->name, name, sizeof t->name);
471   t->stack = (uint8_t *) t + PGSIZE;
472   t->priority = priority;
473   t->magic = THREAD_MAGIC;
474
475   old_level = intr_disable ();
476   list_push_back (&all_list, &t->allelem);
477   intr_set_level (old_level);
478 }
479
480 /* Allocates a SIZE-byte frame at the top of thread T's stack and
481    returns a pointer to the frame's base. */
482 static void *
483 alloc_frame (struct thread *t, size_t size) 
484 {
485   /* Stack data is always allocated in word-size units. */
486   ASSERT (is_thread (t));
487   ASSERT (size % sizeof (uint32_t) == 0);
488
489   t->stack -= size;
490   return t->stack;
491 }
492
493 /* Chooses and returns the next thread to be scheduled.  Should
494    return a thread from the run queue, unless the run queue is
495    empty.  (If the running thread can continue running, then it
496    will be in the run queue.)  If the run queue is empty, return
497    idle_thread. */
498 static struct thread *
499 next_thread_to_run (void) 
500 {
501   if (list_empty (&ready_list))
502     return idle_thread;
503   else
504     return list_entry (list_pop_front (&ready_list), struct thread, elem);
505 }
506
507 /* Completes a thread switch by activating the new thread's page
508    tables, and, if the previous thread is dying, destroying it.
509
510    At this function's invocation, we just switched from thread
511    PREV, the new thread is already running, and interrupts are
512    still disabled.  This function is normally invoked by
513    thread_schedule() as its final action before returning, but
514    the first time a thread is scheduled it is called by
515    switch_entry() (see switch.S).
516
517    It's not safe to call printf() until the thread switch is
518    complete.  In practice that means that printf()s should be
519    added at the end of the function.
520
521    After this function and its caller returns, the thread switch
522    is complete. */
523 void
524 thread_schedule_tail (struct thread *prev)
525 {
526   struct thread *cur = running_thread ();
527   
528   ASSERT (intr_get_level () == INTR_OFF);
529
530   /* Mark us as running. */
531   cur->status = THREAD_RUNNING;
532
533   /* Start new time slice. */
534   thread_ticks = 0;
535
536 #ifdef USERPROG
537   /* Activate the new address space. */
538   process_activate ();
539 #endif
540
541   /* If the thread we switched from is dying, destroy its struct
542      thread.  This must happen late so that thread_exit() doesn't
543      pull out the rug under itself.  (We don't free
544      initial_thread because its memory was not obtained via
545      palloc().) */
546   if (prev != NULL && prev->status == THREAD_DYING && prev != initial_thread) 
547     {
548       ASSERT (prev != cur);
549       palloc_free_page (prev);
550     }
551 }
552
553 /* Schedules a new process.  At entry, interrupts must be off and
554    the running process's state must have been changed from
555    running to some other state.  This function finds another
556    thread to run and switches to it.
557
558    It's not safe to call printf() until thread_schedule_tail()
559    has completed. */
560 static void
561 schedule (void) 
562 {
563   struct thread *cur = running_thread ();
564   struct thread *next = next_thread_to_run ();
565   struct thread *prev = NULL;
566
567   ASSERT (intr_get_level () == INTR_OFF);
568   ASSERT (cur->status != THREAD_RUNNING);
569   ASSERT (is_thread (next));
570
571   if (cur != next)
572     prev = switch_threads (cur, next);
573   thread_schedule_tail (prev);
574 }
575
576 /* Returns a tid to use for a new thread. */
577 static tid_t
578 allocate_tid (void) 
579 {
580   static tid_t next_tid = 1;
581   tid_t tid;
582
583   lock_acquire (&tid_lock);
584   tid = next_tid++;
585   lock_release (&tid_lock);
586
587   return tid;
588 }
589 \f
590 /* Offset of `stack' member within `struct thread'.
591    Used by switch.S, which can't figure it out on its own. */
592 uint32_t thread_stack_ofs = offsetof (struct thread, stack);