Fixed corner case with alarm rel_time
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 5 May 2011 01:26:43 +0000 (18:26 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:36:02 +0000 (17:36 -0700)
With rounding errors when time > now, you could get rel_time == 0, which
shuts off the alarm.

For those curious, the time on hardware to set a 1 usec alarm, sleep on
it, and wake back up is around 3.1 usec, depending on cache hotness.

kern/arch/i686/apic.c
kern/src/alarm.c

index 4cd92e8..c6411e7 100644 (file)
@@ -86,6 +86,7 @@ void lapic_set_timer(uint32_t usec, bool periodic)
 {
        // divide the bus clock by 128, which is the max.
        uint32_t ticks = (usec * system_timing.bus_freq / 128) / 1000000;
+       assert(ticks > 0);
        __lapic_set_timer(ticks, LAPIC_TIMER_DEFAULT_VECTOR, periodic,
                          LAPIC_TIMER_DEFAULT_DIVISOR);
 }
index 9b6809f..41a99de 100644 (file)
@@ -240,7 +240,8 @@ void set_pcpu_alarm_interrupt(uint64_t time, struct timer_chain *tchain)
                if (time <= now)
                        rel_usec = 1;
                else
-                       rel_usec = ((time - now) / (system_timing.tsc_freq / 1000000));
+                       rel_usec = (time - now) / (system_timing.tsc_freq / 1000000);
+               rel_usec = MAX(rel_usec, 1);
                printd("Setting alarm for %llu, it is now %llu, rel_time %llu "
                       "tchain %08p\n", time, now, rel_usec, pcpui_tchain);
                /* Note that sparc doesn't honor the one-shot setting, so you might get