Make yield_on_return only usable in an external interrupt context: (1)
[pintos-anon] / src / threads / interrupt.c
index 0d7b119f696c3cc32e459421e49d4967123b2b36..dc4b31ba3d5a0256f57fd1a0bc84aae15419d7e8 100644 (file)
@@ -117,16 +117,13 @@ intr_name (int vec)
 void
 intr_handler (struct intr_frame *args) 
 {
-  bool external;
-  
-  yield_on_return = false;
-
-  external = args->vec_no >= 0x20 && args->vec_no < 0x30;
+  bool external = args->vec_no >= 0x20 && args->vec_no < 0x30;
   if (external) 
     {
       ASSERT (intr_get_level () == IF_OFF);
       ASSERT (!intr_context ());
       intr_in_progress = true;
+      yield_on_return = false;
     }
 
   intr_handlers[args->vec_no] (args);
@@ -137,10 +134,10 @@ intr_handler (struct intr_frame *args)
       ASSERT (intr_context ());
       intr_in_progress = false;
       pic_eoi (); 
-    }
 
-  if (yield_on_return) 
-    thread_yield (); 
+      if (yield_on_return) 
+        thread_yield (); 
+    }
 }
 
 bool
@@ -152,6 +149,7 @@ intr_context (void)
 void
 intr_yield_on_return (void) 
 {
+  ASSERT (intr_context ());
   yield_on_return = true;
 }
 
@@ -184,17 +182,18 @@ make_trap_gate (void (*target) (void), int dpl)
   return make_gate (target, dpl, TYPE_TRAP_32);
 }
 
-/* We don't support nested interrupts generated by external
-   hardware, so these interrupts (vec_no 0x20...0x2f) should
-   specify IF_OFF for LEVEL.  Otherwise a timer interrupt could
-   cause a task switch during interrupt handling.  Most other
-   interrupts can and should be handled with interrupts
-   enabled. */
 void
 intr_register (uint8_t vec_no, int dpl, enum if_level level,
                intr_handler_func *handler,
                const char *name) 
 {
+  /* Interrupts generated by external hardware (0x20 <= VEC_NO <=
+     0x2f) should specify IF_OFF for LEVEL.  Otherwise a timer
+     interrupt could cause a task switch during interrupt
+     handling.  Most other interrupts can and should be handled
+     with interrupts enabled. */
+  ASSERT (vec_no < 0x20 || vec_no > 0x2f || level == IF_OFF);
+
   if (level == IF_ON)
     idt[vec_no] = make_trap_gate (intr_stubs[vec_no], dpl);
   else