9 uint32_t thread_stack_ofs = offsetof (struct thread, stack);
11 static struct list run_queue;
13 struct thread *thread_switch (struct thread *cur, struct thread *next);
18 list_init (&run_queue);
22 thread_root (void (*function) (void *aux), void *aux)
24 ASSERT (function != NULL);
31 thread_create (const char *name, void (*function) (void *aux), void *aux)
35 ASSERT (name != NULL);
36 ASSERT (function != NULL);
43 strlcpy (t->name, name, sizeof t->name);
46 t->stack = (uint32_t *) ((uint8_t *) t + NBPG);
47 *--t->stack = (uint32_t) aux;
48 *--t->stack = (uint32_t) function;
50 *--t->stack = (uint32_t) thread_root;
53 /* Add to run_queue. */
54 t->status = THREAD_BLOCKED;
60 static struct thread *
61 stack_to_thread (uint32_t *stack)
63 return (struct thread *) ((uint32_t) (stack - 1) & ~((uint32_t) NBPG - 1));
70 asm ("movl %%esp, %0\n" : "=g" (esp));
71 return stack_to_thread (esp);
75 thread_ready (struct thread *t)
77 if (t->status != THREAD_READY)
79 list_push_back (&run_queue, &t->rq_elem);
80 t->status = THREAD_READY;
84 static struct thread *
85 find_next_to_run (void)
87 if (list_empty (&run_queue))
90 return list_entry (list_pop_front (&run_queue), struct thread, rq_elem);
102 thread_destroy (struct thread *t)
104 ASSERT (t->status == THREAD_DYING);
105 ASSERT (t != thread_current ());
111 thread_schedule (void)
113 struct thread *cur, *next, *prev;
115 cur = thread_current ();
116 ASSERT (cur->status != THREAD_RUNNING);
118 while ((next = find_next_to_run ()) == NULL)
121 next->status = THREAD_RUNNING;
122 prev = thread_switch (cur, next);
123 if (prev != NULL && prev->status == THREAD_DYING)
124 thread_destroy (prev);
130 ASSERT (!intr_context ());
131 thread_ready (thread_current ());
136 thread_start (struct thread *t)
138 if (t->status == THREAD_READY)
139 list_remove (&t->rq_elem);
140 t->status = THREAD_RUNNING;
141 thread_switch (NULL, t);
147 struct thread *t = thread_current ();
148 t->status = THREAD_DYING;
155 ASSERT (intr_get_level () == IF_OFF);
157 thread_current ()->status = THREAD_BLOCKED;