X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pintos-anon;a=blobdiff_plain;f=src%2Fthreads%2Finterrupt.c;h=e3b90dcb566e3512b8ea1b9e69d2544d64e5933b;hp=9ffd873540b803ca3414b83f10c6da4e8c4b2f54;hb=ffdf5a5f292d3ae73f62422ad66297eb84da26c4;hpb=6ffbc2b68c34c2d1e42d5f6bcd8f2b94b82d05d7 diff --git a/src/threads/interrupt.c b/src/threads/interrupt.c index 9ffd873..e3b90dc 100644 --- a/src/threads/interrupt.c +++ b/src/threads/interrupt.c @@ -33,6 +33,10 @@ static intr_handler_func *intr_handlers[INTR_CNT]; /* Names for each interrupt, for debugging purposes. */ static const char *intr_names[INTR_CNT]; +/* Number of unexpected interrupts for each vector. An + unexpected interrupt is one that has no registered handler. */ +static unsigned int unexpected_cnt[INTR_CNT]; + /* External interrupts are those generated by devices outside the CPU, such as the timer. External interrupts run with interrupts turned off, so they never nest, nor are they ever @@ -54,6 +58,7 @@ static inline uint64_t make_idtr_operand (uint16_t limit, void *base); /* Interrupt handlers. */ void intr_handler (struct intr_frame *args); +static void unexpected_interrupt (const struct intr_frame *); /* Returns the current interrupt status. */ enum intr_level @@ -366,13 +371,8 @@ intr_handler (struct intr_frame *frame) spuriously due to a hardware fault or hardware race condition. Ignore it. */ } - else - { - /* No handler and not spurious. Invoke the unexpected - interrupt handler. */ - intr_dump_frame (frame); - PANIC ("Unexpected interrupt"); - } + else + unexpected_interrupt (frame); /* Complete the processing of an external interrupt. */ if (external) @@ -388,6 +388,24 @@ intr_handler (struct intr_frame *frame) } } +/* Handles an unexpected interrupt with interrupt frame F. An + unexpected interrupt is one that has no registered handler. */ +static void +unexpected_interrupt (const struct intr_frame *f) +{ + /* Count the number so far. */ + unsigned int n = ++unexpected_cnt[f->vec_no]; + + /* If the number is a power of 2, print a message. This rate + limiting means that we get information about an uncommon + unexpected interrupt the first time and fairly often after + that, but one that occurs many times will not overwhelm the + console. */ + if ((n & (n - 1)) == 0) + printf ("Unexpected interrupt %#04x (%s)\n", + f->vec_no, intr_names[f->vec_no]); +} + /* Dumps interrupt frame F to the console, for debugging. */ void intr_dump_frame (const struct intr_frame *f)