int main(int argc, char **argv) { int enabled; thread_init(); /* show interrupt handler output */ register_interrupt_handler(1); test(1); /* test interrupts_on/off/set */ enabled = interrupts_off(); assert(enabled); test(0); enabled = interrupts_off(); assert(!enabled); test(0); enabled = interrupts_set(1); assert(!enabled); test(1); enabled = interrupts_set(1); assert(enabled); test(1); exit(0); }
static void test_wakeup_thread(int num) { int i; int ret; struct timeval start, end, diff; for (i = 0; i < LOOPS; i++) { int enabled; gettimeofday(&start, NULL); /* track the number of sleeping threads with interrupts * disabled to avoid wakeup races. */ enabled = interrupts_off(); assert(enabled); __sync_fetch_and_add(&nr_sleeping, 1); ret = thread_sleep(queue); assert(thread_ret_ok(ret)); interrupts_set(enabled); gettimeofday(&end, NULL); timersub(&end, &start, &diff); /* thread_sleep should wait at least 4-5 ms */ if (diff.tv_sec == 0 && diff.tv_usec < 4000) { unintr_printf("%s took %ld us. That's too fast." " You must be busy looping\n", __FUNCTION__, diff.tv_usec); goto out; } } out: __sync_fetch_and_add(&done, 1); }
static void show_interrupt(void) { int err; /* QUESTION: how did we get here if there was an assert above? */ /* now think about interrupts. you will need to understand how they * work, and how they interact with get/setcontext for implementing * preemptive threading. */ /* QUESTION: what does interrupts_on() do? see interrupt.c */ interrupts_on(); /* getcontext stores the process's signal mask */ err = getcontext(&mycontext); assert(!err); /* QUESTION: Are interrupts masked (i.e., disabled) in mycontext? * HINT: use sigismember below. */ printf("interrupt is disabled = %d\n", (unsigned int) sigismember(&mycontext.uc_sigmask, SIG_TYPE)); interrupts_off(); err = getcontext(&mycontext); assert(!err); /* QUESTION: which fields of mycontext changed as a result of the * getcontext call above? */ printf("interrupt is disabled = %d\n", (unsigned int) sigismember(&mycontext.uc_sigmask, SIG_TYPE)); }
/* turn off interrupts while printing */ int unintr_printf(const char *fmt, ...) { int ret, enabled; va_list args; enabled = interrupts_off(); va_start(args, fmt); ret = vprintf(fmt, args); va_end(args); interrupts_set(enabled); return ret; }