Move user exception support into userprog.
[pintos-anon] / src / threads / thread.c
index 540041d4d0c57eb476ff0d9eecd3c950913866a3..d89edd6c8dcad5dcbe9cae5f21c2273c19be1f4d 100644 (file)
@@ -8,6 +8,9 @@
 #include "palloc.h"
 #include "random.h"
 #include "switch.h"
+#ifdef USERPROG
+#include "gdt.h"
+#endif
 
 #define THREAD_MAGIC 0x1234abcdu
 
@@ -23,11 +26,11 @@ static void idle (void *aux UNUSED);    /* Thread function. */
 struct kernel_thread_frame 
   {
     void *eip;                  /* Return address. */
-    void (*function) (void *);  /* Function to call. */
+    thread_func *function;      /* Function to call. */
     void *aux;                  /* Auxiliary data for function. */
   };
 
-static void kernel_thread (void (*function) (void *aux), void *aux);
+static void kernel_thread (thread_func *, void *aux);
 
 static struct thread *next_thread_to_run (void);
 static struct thread *new_thread (const char *name);
@@ -43,7 +46,7 @@ void schedule_tail (struct thread *prev);
 void
 thread_init (void) 
 {
-  ASSERT (intr_get_level () == IF_OFF);
+  ASSERT (intr_get_level () == INTR_OFF);
 
   /* Initialize run queue. */
   list_init (&run_queue);
@@ -75,7 +78,7 @@ thread_start (void)
    semaphore or some other form of synchronization if you need to
    ensure ordering. */
 struct thread *
-thread_create (const char *name, void (*function) (void *aux), void *aux) 
+thread_create (const char *name, thread_func *function, void *aux) 
 {
   struct thread *t;
   struct kernel_thread_frame *kf;
@@ -135,7 +138,7 @@ thread_execute (const char *filename)
   if_->ds = SEL_UDSEG;
   if_->eip = start;
   if_->cs = SEL_UCSEG;
-  if_->eflags = FLAG_IF | 2;
+  if_->eflags = FLAG_IF | FLAG_MBS;
   if_->esp = PHYS_BASE;
   if_->ss = SEL_UDSEG;
 
@@ -220,7 +223,7 @@ void
 thread_yield (void) 
 {
   struct thread *cur = thread_current ();
-  enum if_level old_level;
+  enum intr_level old_level;
   
   ASSERT (!intr_context ());
 
@@ -237,7 +240,7 @@ void
 thread_sleep (void) 
 {
   ASSERT (!intr_context ());
-  ASSERT (intr_get_level () == IF_OFF);
+  ASSERT (intr_get_level () == INTR_OFF);
 
   thread_current ()->status = THREAD_BLOCKED;
   schedule ();
@@ -262,7 +265,7 @@ idle (void *aux UNUSED)
 
 /* Function used as the basis for a kernel thread. */
 static void
-kernel_thread (void (*function) (void *aux), void *aux) 
+kernel_thread (thread_func *function, void *aux) 
 {
   ASSERT (function != NULL);
 
@@ -336,7 +339,9 @@ destroy_thread (struct thread *t)
   ASSERT (t->status == THREAD_DYING);
   ASSERT (t != thread_current ());
 
+#ifdef USERPROG
   addrspace_destroy (t);
+#endif
   palloc_free (t);
 }
 
@@ -357,7 +362,7 @@ schedule_tail (struct thread *prev)
 {
   struct thread *cur = thread_current ();
   
-  ASSERT (intr_get_level () == IF_OFF);
+  ASSERT (intr_get_level () == INTR_OFF);
 
   cur->status = THREAD_RUNNING;
   if (prev != NULL && prev->status == THREAD_DYING) 
@@ -378,7 +383,7 @@ schedule (void)
   struct thread *cur = thread_current ();
   struct thread *next = next_thread_to_run ();
 
-  ASSERT (intr_get_level () == IF_OFF);
+  ASSERT (intr_get_level () == INTR_OFF);
   ASSERT (cur->status != THREAD_RUNNING);
   ASSERT (is_thread (next));