Fixes re-arming alarms from IRQ handlers
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 2 Mar 2015 15:56:19 +0000 (10:56 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 2 Mar 2015 15:56:19 +0000 (10:56 -0500)
commit72fb69c1ff8d5c64cac61d16d797f8821faf8d8f
treee9da569e29423f43818dc808c0835bf812ff7db5
parentb0f15978675637554f4e89deb6c8a96b20937768
Fixes re-arming alarms from IRQ handlers

Previously, you had to call __set_alarm(), since the tchain lock was
held.  This made it more difficult to work with, and easy to
accidentally use the wrong type of set_alarm().  For IRQ handlers, you'd
quickly deadlock.  But RKM handlers using __set_alarm() could silently
corrupt the tchain.

This commit pushes the logic about whether or not the tchain lock is
held into the alarm code, so users can call set_alarm (or reset) without
worrying about the context.

Also, this clarifies the differences between the cancellation guarantees
between IRQ and RKM handlers.  In short, if you fail to cancel an RKM
alarm, it is possible that the alarm handler has not executed yet, but
it will eventually.  In these cases, do not free the waiter til after it
executes.  A bad practice would be:
unset_alarm(some-rkm-alarm-waiter);
// think it has already fired and no refs to waiter exist
kfree(the-waiter);
You *can* do that with IRQ alarms.  That's the price you pay for using
the RKM alarm.

We can build something more intense so that you can sleep on an RKM
alarm's completion, but I won't do it until someone expresses a need
(and feedback so far is no one wants it).
kern/drivers/dev/kprof.c
kern/include/alarm.h
kern/src/alarm.c