/* List of processes in THREAD_READY state, that is, processes
that are ready to run but not actually running. */
-static struct list run_queue;
+static struct list ready_list;
/* Idle thread. */
static struct thread *idle_thread; /* Thread. */
static void idle (void *aux UNUSED); /* Thread function. */
+/* Initial thread.
+ This is the thread running main(). */
+static struct thread *initial_thread;
+
/* Stack frame for kernel_thread(). */
struct kernel_thread_frame
{
void
thread_init (void)
{
- struct thread *t;
-
ASSERT (intr_get_level () == INTR_OFF);
/* Set up a thread structure for the running thread. */
- t = running_thread ();
- init_thread (t, "main");
- t->status = THREAD_RUNNING;
+ initial_thread = running_thread ();
+ init_thread (initial_thread, "main");
+ initial_thread->status = THREAD_RUNNING;
/* Initialize run queue. */
- list_init (&run_queue);
+ list_init (&ready_list);
}
/* Starts preemptive thread scheduling by enabling interrupts.
old_level = intr_disable ();
if (t->status == THREAD_BLOCKED)
{
- list_push_back (&run_queue, &t->elem);
+ list_push_back (&ready_list, &t->elem);
t->status = THREAD_READY;
}
intr_set_level (old_level);
ASSERT (!intr_context ());
old_level = intr_disable ();
- list_push_back (&run_queue, &cur->elem);
+ list_push_back (&ready_list, &cur->elem);
cur->status = THREAD_READY;
schedule ();
intr_set_level (old_level);
static struct thread *
next_thread_to_run (void)
{
- if (list_empty (&run_queue))
+ if (list_empty (&ready_list))
return idle_thread;
else
- return list_entry (list_pop_front (&run_queue), struct thread, elem);
+ return list_entry (list_pop_front (&ready_list), struct thread, elem);
}
/* Destroys T, which must be in the dying state and must not be
#ifdef USERPROG
addrspace_destroy (t);
#endif
- palloc_free (t);
+ if (t != initial_thread)
+ palloc_free (t);
}
/* Completes a thread switch by activating the new thread's page