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);
ASSERT (intr_context ());
intr_in_progress = false;
pic_eoi ();
- }
- if (yield_on_return)
- thread_yield ();
+ if (yield_on_return)
+ thread_yield ();
+ }
}
bool
void
intr_yield_on_return (void)
{
+ ASSERT (intr_context ());
yield_on_return = true;
}
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