+thread_exit (void)
+{
+ ASSERT (!intr_context ());
+
+ /* Just set our status to dying and schedule another process.
+ We will be destroyed during the call to schedule_tail(). */
+ intr_disable ();
+ thread_current ()->status = THREAD_DYING;
+ schedule ();
+ NOT_REACHED ();
+}
+
+/* Yields the CPU. The current thread is not put to sleep and
+ may be scheduled again immediately at the scheduler's whim. */
+void
+thread_yield (void)
+{
+ struct thread *cur = thread_current ();
+ enum intr_level old_level;
+
+ ASSERT (!intr_context ());
+
+ old_level = intr_disable ();
+ list_push_back (&ready_list, &cur->elem);
+ cur->status = THREAD_READY;
+ schedule ();
+ intr_set_level (old_level);
+}
+
+/* Puts the current thread to sleep. It will not be scheduled
+ again until awoken by thread_unblock().
+
+ This function must be called with interrupts turned off. It
+ is usually a better idea to use one of the synchronization
+ primitives in synch.h. */
+void
+thread_block (void)
+{
+ ASSERT (!intr_context ());
+ ASSERT (intr_get_level () == INTR_OFF);
+
+ thread_current ()->status = THREAD_BLOCKED;
+ schedule ();
+}
+\f
+/* Idle thread. Executes when no other thread is ready to run. */
+static void
+idle (void *aux UNUSED)