1 #include "threads/thread.h"
6 #include "threads/interrupt.h"
7 #include "threads/intr-stubs.h"
8 #include "threads/mmu.h"
9 #include "threads/palloc.h"
10 #include "threads/switch.h"
11 #include "threads/synch.h"
13 #include "userprog/gdt.h"
16 /* Random value for struct thread's `magic' member.
17 Used to detect stack overflow. See the big comment at the top
18 of thread.h for details. */
19 #define THREAD_MAGIC 0xcd6abf4b
21 /* List of processes in THREAD_READY state, that is, processes
22 that are ready to run but not actually running. */
23 static struct list ready_list;
26 static struct thread *idle_thread;
28 /* Initial thread, the thread running init.c:main(). */
29 static struct thread *initial_thread;
31 /* Lock used by allocate_tid(). */
32 static struct lock tid_lock;
34 /* Stack frame for kernel_thread(). */
35 struct kernel_thread_frame
37 void *eip; /* Return address. */
38 thread_func *function; /* Function to call. */
39 void *aux; /* Auxiliary data for function. */
42 static void kernel_thread (thread_func *, void *aux);
44 static void idle (void *aux UNUSED);
45 static struct thread *running_thread (void);
46 static struct thread *next_thread_to_run (void);
47 static struct thread *new_thread (const char *name);
48 static void init_thread (struct thread *, const char *name);
49 static bool is_thread (struct thread *);
50 static void *alloc_frame (struct thread *, size_t size);
51 static void destroy_thread (struct thread *);
52 static void schedule (void);
53 void schedule_tail (struct thread *prev);
54 static tid_t allocate_tid (void);
56 /* Initializes the threading system by transforming the code
57 that's currently running into a thread. Note that this is
58 possible only because the loader was careful to put the bottom
59 of the stack at a page boundary; it won't work in general.
60 Also initializes the run queue.
62 After calling this function, be sure to initialize the page
63 allocator before trying to create any threads with
68 ASSERT (intr_get_level () == INTR_OFF);
70 lock_init (&tid_lock, "tid");
72 /* Set up a thread structure for the running thread. */
73 initial_thread = running_thread ();
74 init_thread (initial_thread, "main");
75 initial_thread->status = THREAD_RUNNING;
76 initial_thread->tid = allocate_tid ();
78 /* Initialize run queue. */
79 list_init (&ready_list);
82 /* Starts preemptive thread scheduling by enabling interrupts.
83 Also creates the idle thread. */
87 thread_create ("idle", idle, NULL);
91 /* Creates a new kernel thread named NAME, which executes
92 FUNCTION passing AUX as the argument, and adds it to the ready
93 queue. If thread_start() has been called, then the new thread
94 may be scheduled before thread_create() returns. It could
95 even exit before thread_create() returns. Use a semaphore or
96 some other form of synchronization if you need to ensure
97 ordering. Returns the thread identifier for the new thread,
98 or TID_ERROR if creation fails. */
100 thread_create (const char *name, thread_func *function, void *aux)
103 struct kernel_thread_frame *kf;
104 struct switch_entry_frame *ef;
105 struct switch_threads_frame *sf;
108 ASSERT (function != NULL);
110 t = new_thread (name);
113 tid = t->tid = allocate_tid ();
115 /* Stack frame for kernel_thread(). */
116 kf = alloc_frame (t, sizeof *kf);
118 kf->function = function;
121 /* Stack frame for switch_entry(). */
122 ef = alloc_frame (t, sizeof *ef);
123 ef->eip = (void (*) (void)) kernel_thread;
125 /* Stack frame for switch_threads(). */
126 sf = alloc_frame (t, sizeof *sf);
127 sf->eip = switch_entry;
129 /* Add to run queue. */
136 /* Starts a new thread running a user program loaded from
137 FILENAME, and adds it to the ready queue. If thread_start()
138 has been called, then new thread may be scheduled before
139 thread_execute() returns.*/
141 thread_execute (const char *filename)
144 struct intr_frame *if_;
145 struct switch_entry_frame *ef;
146 struct switch_threads_frame *sf;
147 void (*start) (void);
150 ASSERT (filename != NULL);
152 t = new_thread (filename);
155 tid = t->tid = allocate_tid ();
157 if (!addrspace_load (t, filename, &start))
158 PANIC ("%s: program load failed", filename);
160 /* Interrupt frame. */
161 if_ = alloc_frame (t, sizeof *if_);
166 if_->eflags = FLAG_IF | FLAG_MBS;
167 if_->esp = PHYS_BASE;
170 /* Stack frame for switch_entry(). */
171 ef = alloc_frame (t, sizeof *ef);
174 /* Stack frame for switch_threads(). */
175 sf = alloc_frame (t, sizeof *sf);
176 sf->eip = switch_entry;
178 /* Add to run queue. */
185 /* Transitions a blocked thread T from its current state to the
186 ready-to-run state. If T is not blocked, there is no effect.
187 (Use thread_yield() to make the running thread ready.) */
189 thread_unblock (struct thread *t)
191 enum intr_level old_level;
193 ASSERT (is_thread (t));
195 old_level = intr_disable ();
196 if (t->status == THREAD_BLOCKED)
198 list_push_back (&ready_list, &t->elem);
199 t->status = THREAD_READY;
201 intr_set_level (old_level);
204 /* Returns the name of the running thread. */
208 return thread_current ()->name;
211 /* Returns the running thread.
212 This is running_thread() plus a couple of sanity checks.
213 See the big comment at the top of thread.h for details. */
215 thread_current (void)
217 struct thread *t = running_thread ();
219 /* Make sure T is really a thread.
220 If either of these assertions fire, then your thread may
221 have overflowed its stack. Each thread has less than 4 kB
222 of stack, so a few big automatic arrays or moderate
223 recursion can cause stack overflow. */
224 ASSERT (is_thread (t));
225 ASSERT (t->status == THREAD_RUNNING);
230 /* Returns the running thread's tid. */
234 return thread_current ()->tid;
237 /* Deschedules the current thread and destroys it. Never
238 returns to the caller. */
242 ASSERT (!intr_context ());
244 /* Just set our status to dying and schedule another process.
245 We will be destroyed during the call to schedule_tail(). */
247 thread_current ()->status = THREAD_DYING;
252 /* Yields the CPU. The current thread is not put to sleep and
253 may be scheduled again immediately at the scheduler's whim. */
257 struct thread *cur = thread_current ();
258 enum intr_level old_level;
260 ASSERT (!intr_context ());
262 old_level = intr_disable ();
263 list_push_back (&ready_list, &cur->elem);
264 cur->status = THREAD_READY;
266 intr_set_level (old_level);
269 /* Puts the current thread to sleep. It will not be scheduled
270 again until awoken by thread_unblock().
272 This function must be called with interrupts turned off. It
273 is usually a better idea to use one of the synchronization
274 primitives in synch.h. */
278 ASSERT (!intr_context ());
279 ASSERT (intr_get_level () == INTR_OFF);
281 thread_current ()->status = THREAD_BLOCKED;
285 /* Idle thread. Executes when no other thread is ready to run. */
287 idle (void *aux UNUSED)
289 idle_thread = thread_current ();
293 /* Let someone else run. */
298 /* Use CPU `hlt' instruction to wait for interrupt. */
303 /* Function used as the basis for a kernel thread. */
305 kernel_thread (thread_func *function, void *aux)
307 ASSERT (function != NULL);
309 intr_enable (); /* The scheduler runs with interrupts off. */
310 function (aux); /* Execute the thread function. */
311 thread_exit (); /* If function() returns, kill the thread. */
314 /* Returns the running thread. */
316 running_thread (void)
320 /* Copy the CPU's stack pointer into `esp', and then round that
321 down to the start of a page. Because `struct thread' is
322 always at the beginning of a page and the stack pointer is
323 somewhere in the middle, this locates the curent thread. */
324 asm ("movl %%esp, %0\n" : "=g" (esp));
325 return pg_round_down (esp);
328 /* Returns true if T appears to point to a valid thread. */
330 is_thread (struct thread *t)
332 return t != NULL && t->magic == THREAD_MAGIC;
335 /* Creates a new thread named NAME and initializes its fields.
336 Returns the new thread if successful or a null pointer on
338 static struct thread *
339 new_thread (const char *name)
343 ASSERT (name != NULL);
345 t = palloc_get (PAL_ZERO);
347 init_thread (t, name);
352 /* Initializes T as a new, blocked thread named NAME. */
354 init_thread (struct thread *t, const char *name)
356 memset (t, 0, sizeof *t);
357 t->status = THREAD_BLOCKED;
358 strlcpy (t->name, name, sizeof t->name);
359 t->stack = (uint8_t *) t + PGSIZE;
360 t->magic = THREAD_MAGIC;
363 /* Allocates a SIZE-byte frame at the top of thread T's stack and
364 returns a pointer to the frame's base. */
366 alloc_frame (struct thread *t, size_t size)
368 /* Stack data is always allocated in word-size units. */
369 ASSERT (is_thread (t));
370 ASSERT (size % sizeof (uint32_t) == 0);
376 /* Chooses and returns the next thread to be scheduled. Should
377 return a thread from the run queue, unless the run queue is
378 empty. (If the running thread can continue running, then it
379 will be in the run queue.) If the run queue is empty, return
381 static struct thread *
382 next_thread_to_run (void)
384 if (list_empty (&ready_list))
387 return list_entry (list_pop_front (&ready_list), struct thread, elem);
390 /* Destroys T, which must be in the dying state and must not be
391 the running thread. */
393 destroy_thread (struct thread *t)
395 ASSERT (is_thread (t));
396 ASSERT (t->status == THREAD_DYING);
397 ASSERT (t != thread_current ());
400 addrspace_destroy (t);
402 if (t != initial_thread)
406 /* Completes a thread switch by activating the new thread's page
407 tables, and, if the previous thread is dying, destroying it.
409 At this function's invocation, we just switched from thread
410 PREV, the new thread is already running, and interrupts are
411 still disabled. This function is normally invoked by
412 thread_schedule() as its final action before returning, but
413 the first time a thread is scheduled it is called by
414 switch_entry() (see switch.S).
416 After this function and its caller returns, the thread switch
419 schedule_tail (struct thread *prev)
421 struct thread *cur = running_thread ();
423 ASSERT (intr_get_level () == INTR_OFF);
425 /* Mark us as running. */
426 cur->status = THREAD_RUNNING;
429 /* Activate the new address space. */
430 addrspace_activate (cur);
433 /* If the thread we switched from is dying, destroy it.
434 This must happen late because it's not a good idea to
435 e.g. destroy the page table you're currently using. */
436 if (prev != NULL && prev->status == THREAD_DYING)
437 destroy_thread (prev);
440 /* Schedules a new process. At entry, interrupts must be off and
441 the running process's state must have been changed from
442 running to some other state. This function finds another
443 thread to run and switches to it. */
447 struct thread *cur = running_thread ();
448 struct thread *next = next_thread_to_run ();
449 struct thread *prev = NULL;
451 ASSERT (intr_get_level () == INTR_OFF);
452 ASSERT (cur->status != THREAD_RUNNING);
453 ASSERT (is_thread (next));
456 prev = switch_threads (cur, next);
457 schedule_tail (prev);
460 /* Returns a tid to use for a new thread. */
464 static tid_t next_tid = 1;
467 lock_acquire (&tid_lock);
469 lock_release (&tid_lock);
474 /* Offset of `stack' member within `struct thread'.
475 Used by switch.S, which can't figure it out on its own. */
476 uint32_t thread_stack_ofs = offsetof (struct thread, stack);