1 #include "threads/thread.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"
15 #include "userprog/gdt.h"
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
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;
28 static struct thread *idle_thread;
30 /* Initial thread, the thread running init.c:main(). */
31 static struct thread *initial_thread;
33 /* Lock used by allocate_tid(). */
34 static struct lock tid_lock;
36 /* Stack frame for kernel_thread(). */
37 struct kernel_thread_frame
39 void *eip; /* Return address. */
40 thread_func *function; /* Function to call. */
41 void *aux; /* Auxiliary data for function. */
44 static void kernel_thread (thread_func *, void *aux);
46 static void idle (void *aux UNUSED);
47 static struct thread *running_thread (void);
48 static struct thread *next_thread_to_run (void);
49 static struct thread *new_thread (const char *name, int priority);
50 static void init_thread (struct thread *, const char *name, int priority);
51 static bool is_thread (struct thread *);
52 static void *alloc_frame (struct thread *, size_t size);
53 static void destroy_thread (struct thread *);
54 static void schedule (void);
55 void schedule_tail (struct thread *prev);
56 static tid_t allocate_tid (void);
58 /* Initializes the threading system by transforming the code
59 that's currently running into a thread. Note that this is
60 possible only because the loader was careful to put the bottom
61 of the stack at a page boundary; it won't work in general.
62 Also initializes the run queue.
64 After calling this function, be sure to initialize the page
65 allocator before trying to create any threads with
70 ASSERT (intr_get_level () == INTR_OFF);
72 lock_init (&tid_lock, "tid");
74 /* Set up a thread structure for the running thread. */
75 initial_thread = running_thread ();
76 init_thread (initial_thread, "main", PRI_DEFAULT);
77 initial_thread->status = THREAD_RUNNING;
78 initial_thread->tid = allocate_tid ();
80 /* Initialize run queue. */
81 list_init (&ready_list);
84 /* Starts preemptive thread scheduling by enabling interrupts.
85 Also creates the idle thread. */
89 thread_create ("idle", PRI_DEFAULT, idle, NULL);
93 /* Creates a new kernel thread named NAME with the given initial
94 PRIORITY, which executes FUNCTION passing AUX as the argument,
95 and adds it to the ready queue. If thread_start() has been
96 called, then the new thread may be scheduled before
97 thread_create() returns. It could even exit before
98 thread_create() returns. Use a semaphore or some other form
99 of synchronization if you need to ensure ordering. Returns
100 the thread identifier for the new thread, or TID_ERROR if
103 The code provided sets the new thread's `priority' member to
104 PRIORITY, but no actual priority scheduling is implemented.
105 Priority scheduling is the goal of Problem 1-3. */
107 thread_create (const char *name, int priority,
108 thread_func *function, void *aux)
111 struct kernel_thread_frame *kf;
112 struct switch_entry_frame *ef;
113 struct switch_threads_frame *sf;
116 ASSERT (function != NULL);
118 t = new_thread (name, priority);
123 /* Stack frame for kernel_thread(). */
124 kf = alloc_frame (t, sizeof *kf);
126 kf->function = function;
129 /* Stack frame for switch_entry(). */
130 ef = alloc_frame (t, sizeof *ef);
131 ef->eip = (void (*) (void)) kernel_thread;
133 /* Stack frame for switch_threads(). */
134 sf = alloc_frame (t, sizeof *sf);
135 sf->eip = switch_entry;
137 /* Add to run queue. */
144 /* Starts a new thread running a user program loaded from
145 FILENAME, and adds it to the ready queue. If thread_start()
146 has been called, then new thread may be scheduled before
147 thread_execute() returns.*/
149 thread_execute (const char *filename)
152 struct intr_frame *if_;
153 struct switch_entry_frame *ef;
154 struct switch_threads_frame *sf;
157 ASSERT (filename != NULL);
159 t = new_thread (filename, PRI_DEFAULT);
164 /* Interrupt frame. */
165 if_ = alloc_frame (t, sizeof *if_);
169 if_->eflags = FLAG_IF | FLAG_MBS;
172 /* Stack frame for switch_entry(). */
173 ef = alloc_frame (t, sizeof *ef);
176 /* Stack frame for switch_threads(). */
177 sf = alloc_frame (t, sizeof *sf);
178 sf->eip = switch_entry;
181 if (!addrspace_load (t, filename, &if_->eip, &if_->esp))
187 /* Add to run queue. */
194 /* Transitions a blocked thread T from its current state to the
195 ready-to-run state. This is an error if T is not blocked.
196 (Use thread_yield() to make the running thread ready.) */
198 thread_unblock (struct thread *t)
200 enum intr_level old_level;
202 ASSERT (is_thread (t));
204 old_level = intr_disable ();
205 ASSERT (t->status == THREAD_BLOCKED);
206 list_push_back (&ready_list, &t->elem);
207 t->status = THREAD_READY;
208 intr_set_level (old_level);
211 /* Returns the name of the running thread. */
215 return thread_current ()->name;
218 /* Returns the running thread.
219 This is running_thread() plus a couple of sanity checks.
220 See the big comment at the top of thread.h for details. */
222 thread_current (void)
224 struct thread *t = running_thread ();
226 /* Make sure T is really a thread.
227 If either of these assertions fire, then your thread may
228 have overflowed its stack. Each thread has less than 4 kB
229 of stack, so a few big automatic arrays or moderate
230 recursion can cause stack overflow. */
231 ASSERT (is_thread (t));
232 ASSERT (t->status == THREAD_RUNNING);
237 /* Returns the running thread's tid. */
241 return thread_current ()->tid;
244 /* Deschedules the current thread and destroys it. Never
245 returns to the caller. */
249 ASSERT (!intr_context ());
251 /* Just set our status to dying and schedule another process.
252 We will be destroyed during the call to schedule_tail(). */
254 thread_current ()->status = THREAD_DYING;
259 /* Yields the CPU. The current thread is not put to sleep and
260 may be scheduled again immediately at the scheduler's whim. */
264 struct thread *cur = thread_current ();
265 enum intr_level old_level;
267 ASSERT (!intr_context ());
269 old_level = intr_disable ();
270 list_push_back (&ready_list, &cur->elem);
271 cur->status = THREAD_READY;
273 intr_set_level (old_level);
276 /* Puts the current thread to sleep. It will not be scheduled
277 again until awoken by thread_unblock().
279 This function must be called with interrupts turned off. It
280 is usually a better idea to use one of the synchronization
281 primitives in synch.h. */
285 ASSERT (!intr_context ());
286 ASSERT (intr_get_level () == INTR_OFF);
288 thread_current ()->status = THREAD_BLOCKED;
292 /* Idle thread. Executes when no other thread is ready to run. */
294 idle (void *aux UNUSED)
296 idle_thread = thread_current ();
300 /* Let someone else run. */
305 /* Use CPU `hlt' instruction to wait for interrupt. */
310 /* Function used as the basis for a kernel thread. */
312 kernel_thread (thread_func *function, void *aux)
314 ASSERT (function != NULL);
316 intr_enable (); /* The scheduler runs with interrupts off. */
317 function (aux); /* Execute the thread function. */
318 thread_exit (); /* If function() returns, kill the thread. */
321 /* Returns the running thread. */
323 running_thread (void)
327 /* Copy the CPU's stack pointer into `esp', and then round that
328 down to the start of a page. Because `struct thread' is
329 always at the beginning of a page and the stack pointer is
330 somewhere in the middle, this locates the curent thread. */
331 asm ("movl %%esp, %0\n" : "=g" (esp));
332 return pg_round_down (esp);
335 /* Returns true if T appears to point to a valid thread. */
337 is_thread (struct thread *t)
339 return t != NULL && t->magic == THREAD_MAGIC;
342 /* Creates a new thread named NAME as a child of the running
343 thread. Returns the new thread if successful or a null
344 pointer on failure. */
345 static struct thread *
346 new_thread (const char *name, int priority)
348 struct thread *t = palloc_get (PAL_ZERO);
351 init_thread (t, name, priority);
352 t->tid = allocate_tid ();
358 /* Does basic initialization of T as a blocked thread named
361 init_thread (struct thread *t, const char *name, int priority)
364 ASSERT (PRI_MIN <= priority && priority <= PRI_MAX);
365 ASSERT (name != NULL);
367 memset (t, 0, sizeof *t);
368 t->status = THREAD_BLOCKED;
369 strlcpy (t->name, name, sizeof t->name);
370 t->stack = (uint8_t *) t + PGSIZE;
371 t->priority = priority;
372 t->magic = THREAD_MAGIC;
375 /* Allocates a SIZE-byte frame at the top of thread T's stack and
376 returns a pointer to the frame's base. */
378 alloc_frame (struct thread *t, size_t size)
380 /* Stack data is always allocated in word-size units. */
381 ASSERT (is_thread (t));
382 ASSERT (size % sizeof (uint32_t) == 0);
388 /* Chooses and returns the next thread to be scheduled. Should
389 return a thread from the run queue, unless the run queue is
390 empty. (If the running thread can continue running, then it
391 will be in the run queue.) If the run queue is empty, return
393 static struct thread *
394 next_thread_to_run (void)
396 if (list_empty (&ready_list))
399 return list_entry (list_pop_front (&ready_list), struct thread, elem);
402 /* Destroys T, which must not be the running thread. */
404 destroy_thread (struct thread *t)
406 ASSERT (is_thread (t));
407 ASSERT (t != thread_current ());
410 addrspace_destroy (t);
412 if (t != initial_thread)
416 /* Completes a thread switch by activating the new thread's page
417 tables, and, if the previous thread is dying, destroying it.
419 At this function's invocation, we just switched from thread
420 PREV, the new thread is already running, and interrupts are
421 still disabled. This function is normally invoked by
422 thread_schedule() as its final action before returning, but
423 the first time a thread is scheduled it is called by
424 switch_entry() (see switch.S).
426 After this function and its caller returns, the thread switch
429 schedule_tail (struct thread *prev)
431 struct thread *cur = running_thread ();
433 ASSERT (intr_get_level () == INTR_OFF);
435 /* Mark us as running. */
436 cur->status = THREAD_RUNNING;
439 /* Activate the new address space. */
440 addrspace_activate (cur);
443 /* If the thread we switched from is dying, destroy it.
444 This must happen late because it's not a good idea to
445 e.g. destroy the page table you're currently using. */
446 if (prev != NULL && prev->status == THREAD_DYING)
447 destroy_thread (prev);
450 /* Schedules a new process. At entry, interrupts must be off and
451 the running process's state must have been changed from
452 running to some other state. This function finds another
453 thread to run and switches to it. */
457 struct thread *cur = running_thread ();
458 struct thread *next = next_thread_to_run ();
459 struct thread *prev = NULL;
461 ASSERT (intr_get_level () == INTR_OFF);
462 ASSERT (cur->status != THREAD_RUNNING);
463 ASSERT (is_thread (next));
466 prev = switch_threads (cur, next);
467 schedule_tail (prev);
470 /* Returns a tid to use for a new thread. */
474 static tid_t next_tid = 1;
477 lock_acquire (&tid_lock);
479 lock_release (&tid_lock);
484 /* Offset of `stack' member within `struct thread'.
485 Used by switch.S, which can't figure it out on its own. */
486 uint32_t thread_stack_ofs = offsetof (struct thread, stack);