Author: bonefish Date: 2011-05-27 18:52:27 +0200 (Fri, 27 May 2011) New Revision: 41776 Changeset: https://dev.haiku-os.org/changeset/41776 Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/timer.cpp Log: * A timer::schedule_time value 0 is no longer treated specially. In fact it wasn't checked for 0 anywhere anywhere. Now we don't reset it to 0 in timer_interrupt() anymore and don't try to avoid 0 for regular schedule times. * timer_interrupt(): Made periodic timers more precise. The next schedule time is no longer computed based on the current time, but on the last schedule time. We skip complete ticks, if we lag too much behind. Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/timer.cpp =================================================================== --- haiku/branches/developer/bonefish/signals/src/system/kernel/timer.cpp 2011-05-27 16:09:02 UTC (rev 41775) +++ haiku/branches/developer/bonefish/signals/src/system/kernel/timer.cpp 2011-05-27 16:52:27 UTC (rev 41776) @@ -95,7 +95,6 @@ cpuData.events = (timer*)event->next; cpuData.current_event = event; cpuData.current_event_in_progress = 1; - event->schedule_time = 0; release_spinlock(spinlock); @@ -132,13 +131,17 @@ if ((mode & ~B_TIMER_FLAGS) == B_PERIODIC_TIMER && cpuData.current_event != NULL) { // we need to adjust it and add it back to the list - bigtime_t scheduleTime = system_time() + event->period; - if (scheduleTime == 0) { - // if we wrapped around and happen to hit zero, set - // it to one, since zero represents not scheduled - scheduleTime = 1; + event->schedule_time += event->period; + + // If the new schedule time is a full interval or more in the past, + // skip ticks. + bigtime_t now = system_time(); + if (now >= event->schedule_time + event->period) { + // pick the closest tick in the past + event->schedule_time = now + - (now - event->schedule_time) % event->period; } - event->schedule_time = (int64)scheduleTime; + add_event_to_list(event, &cpuData.events); } @@ -177,8 +180,6 @@ scheduleTime = period; if ((flags & ~B_TIMER_FLAGS) != B_ONE_SHOT_ABSOLUTE_TIMER) scheduleTime += currentTime; - if (scheduleTime == 0) - scheduleTime = 1; event->schedule_time = (int64)scheduleTime; event->period = period;