[haiku-commits] r42040 - haiku/branches/developer/bonefish/signals/src/system/kernel

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 8 Jun 2011 04:05:04 +0200 (CEST)

Author: bonefish
Date: 2011-06-08 04:05:04 +0200 (Wed, 08 Jun 2011)
New Revision: 42040
Changeset: https://dev.haiku-os.org/changeset/42040

Modified:
   haiku/branches/developer/bonefish/signals/src/system/kernel/timer.cpp
Log:
* Use a small wrapper function for calling arch_timer_set_hardware_timer().
  Prevent an underflow when computing the timeout to be passed on.
* per_cpu_real_time_clock_changed(): Deal with over-/underflows.
* add_timer(): Prevent a negative schedule_time for absolute real-time timers.


Modified: haiku/branches/developer/bonefish/signals/src/system/kernel/timer.cpp
===================================================================
--- haiku/branches/developer/bonefish/signals/src/system/kernel/timer.cpp       
2011-06-08 01:57:25 UTC (rev 42039)
+++ haiku/branches/developer/bonefish/signals/src/system/kernel/timer.cpp       
2011-06-08 02:05:04 UTC (rev 42040)
@@ -44,6 +44,29 @@
 #endif
 
 
+/*!    Sets the hardware timer to the given absolute time.
+
+       \param scheduleTime The absolute system time for the timer expiration.
+       \param now The current system time.
+*/
+static void
+set_hardware_timer(bigtime_t scheduleTime, bigtime_t now)
+{
+       arch_timer_set_hardware_timer(scheduleTime > now ? scheduleTime - now : 
0);
+}
+
+
+/*!    Sets the hardware timer to the given absolute time.
+
+       \param scheduleTime The absolute system time for the timer expiration.
+*/
+static inline void
+set_hardware_timer(bigtime_t scheduleTime)
+{
+       set_hardware_timer(scheduleTime, system_time());
+}
+
+
 /*! NOTE: expects interrupts to be off */
 static void
 add_event_to_list(timer* event, timer* volatile* list)
@@ -109,17 +132,26 @@
                timer* event = affectedTimers;
                affectedTimers = event->next;
 
+               bigtime_t oldTime = event->schedule_time;
                event->schedule_time += timeDiff;
+
+               // handle over-/underflows
+               if (timeDiff >= 0) {
+                       if (event->schedule_time < oldTime)
+                               event->schedule_time = B_INFINITE_TIMEOUT;
+               } else {
+                       if (event->schedule_time < 0)
+                               event->schedule_time = 0;
+               }
+
                add_event_to_list(event, &cpuData.events);
        }
 
        firstEventChanged |= cpuData.events != firstEvent;
 
        // If the first event has changed, reset the hardware timer.
-       if (firstEventChanged) {
-               arch_timer_set_hardware_timer(
-                       cpuData.events->schedule_time - system_time());
-       }
+       if (firstEventChanged)
+               set_hardware_timer(cpuData.events->schedule_time);
 }
 
 
@@ -289,13 +321,8 @@
        }
 
        // setup the next hardware timer
-       if (cpuData.events != NULL) {
-               bigtime_t timeout = (bigtime_t)cpuData.events->schedule_time
-                       - system_time();
-               if (timeout <= 0)
-                       timeout = 1;
-               arch_timer_set_hardware_timer(timeout);
-       }
+       if (cpuData.events != NULL)
+               set_hardware_timer(cpuData.events->schedule_time);
 
        release_spinlock(spinlock);
 
@@ -342,7 +369,10 @@
        // time to system time.
        if ((flags & ~B_TIMER_FLAGS) == B_ONE_SHOT_ABSOLUTE_TIMER
                && (flags & B_TIMER_REAL_TIME_BASE) != 0) {
-               event->schedule_time -= cpuData.real_time_offset;
+               if (event->schedule_time > cpuData.real_time_offset)
+                       event->schedule_time -= cpuData.real_time_offset;
+               else
+                       event->schedule_time = 0;
        }
 
        add_event_to_list(event, &cpuData.events);
@@ -350,7 +380,7 @@
 
        // if we were stuck at the head of the list, set the hardware timer
        if (event == cpuData.events)
-               arch_timer_set_hardware_timer(scheduleTime - currentTime);
+               set_hardware_timer(scheduleTime, currentTime);
 
        release_spinlock(&cpuData.lock);
        restore_interrupts(state);
@@ -416,10 +446,8 @@
                if (cpu == smp_get_current_cpu()) {
                        if (cpuData.events == NULL)
                                arch_timer_clear_hardware_timer();
-                       else {
-                               arch_timer_set_hardware_timer(
-                                       
(bigtime_t)cpuData.events->schedule_time - system_time());
-                       }
+                       else
+                               
set_hardware_timer(cpuData.events->schedule_time);
                }
 
                return false;


Other related posts:

  • » [haiku-commits] r42040 - haiku/branches/developer/bonefish/signals/src/system/kernel - ingo_weinhold