[haiku-commits] r41937 - in haiku/branches/developer/bonefish/signals: headers/private/kernel src/system/kernel

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 5 Jun 2011 17:46:23 +0200 (CEST)

Author: bonefish
Date: 2011-06-05 17:46:22 +0200 (Sun, 05 Jun 2011)
New Revision: 41937
Changeset: https://dev.haiku-os.org/changeset/41937

Modified:
   haiku/branches/developer/bonefish/signals/headers/private/kernel/UserTimer.h
   haiku/branches/developer/bonefish/signals/src/system/kernel/UserTimer.cpp
Log:
When a team or thread CPU clock are set, update the timers based on the clock.


Modified: 
haiku/branches/developer/bonefish/signals/headers/private/kernel/UserTimer.h
===================================================================
--- 
haiku/branches/developer/bonefish/signals/headers/private/kernel/UserTimer.h    
    2011-06-05 15:03:31 UTC (rev 41936)
+++ 
haiku/branches/developer/bonefish/signals/headers/private/kernel/UserTimer.h    
    2011-06-05 15:46:22 UTC (rev 41937)
@@ -101,6 +101,7 @@
                        void                            Deactivate();
 
                        void                            Update(Thread* 
unscheduledThread);
+                       void                            TimeWarped(bigtime_t 
changedBy);
 
 protected:
        virtual void                            HandleTimer();
@@ -114,6 +115,7 @@
                        bigtime_t                       fNextTime;
                        bigtime_t                       fInterval;
                        int32                           fRunningThreads;
+                       bool                            fAbsolute;
 
 public:
                        // conceptually package private
@@ -136,6 +138,7 @@
 
                        void                            Start();
                        void                            Stop();
+                       void                            TimeWarped(bigtime_t 
changedBy);
 
 protected:
        virtual void                            HandleTimer();
@@ -145,6 +148,7 @@
                        Thread*                         fThread;        // != 
NULL only when active
                        bigtime_t                       fNextTime;
                        bigtime_t                       fInterval;
+                       bool                            fAbsolute;
 
 public:
                        // conceptually package private

Modified: 
haiku/branches/developer/bonefish/signals/src/system/kernel/UserTimer.cpp
===================================================================
--- haiku/branches/developer/bonefish/signals/src/system/kernel/UserTimer.cpp   
2011-06-05 15:03:31 UTC (rev 41936)
+++ haiku/branches/developer/bonefish/signals/src/system/kernel/UserTimer.cpp   
2011-06-05 15:46:22 UTC (rev 41937)
@@ -343,6 +343,11 @@
 }
 
 
+/*!    Called when the real-time clock has been changed.
+
+       The caller must hold the scheduler lock. Optionally the caller may also
+       hold \c sAbsoluteRealTimeTimersLock.
+*/
 void
 RealTimeUserTimer::TimeWarped()
 {
@@ -456,8 +461,10 @@
        if (fTeam == NULL)
                return;
 
+       fAbsolute = (flags & B_RELATIVE_TIMEOUT) == 0;
+
        // convert relative to absolute timeouts
-       if ((flags & B_RELATIVE_TIMEOUT) != 0) {
+       if (!fAbsolute) {
                if (!nowValid)
                        now = fTeam->CPUTime(false);
                fNextTime += now;
@@ -542,7 +549,30 @@
 }
 
 
+/*!    Called when the team's CPU time clock which this timer refers to has 
been
+       set.
+
+       The caller must hold the scheduler lock.
+
+       \param changedBy The value by which the clock has changed.
+*/
 void
+TeamTimeUserTimer::TimeWarped(bigtime_t changedBy)
+{
+       if (fTeam == NULL || changedBy == 0)
+               return;
+
+       // If this is a relative timer, adjust fNextTime by the value the clock 
has
+       // changed.
+       if (!fAbsolute)
+               fNextTime += changedBy;
+
+       // reschedule the kernel timer
+       _Update(false);
+}
+
+
+void
 TeamTimeUserTimer::HandleTimer()
 {
        UserTimer::HandleTimer();
@@ -662,8 +692,10 @@
        if (fThread == NULL)
                return;
 
+       fAbsolute = (flags & B_RELATIVE_TIMEOUT) == 0;
+
        // convert relative to absolute timeouts
-       if ((flags & B_RELATIVE_TIMEOUT) != 0) {
+       if (!fAbsolute) {
                if (!nowValid)
                        now = fThread->CPUTime(false);
                fNextTime += now;
@@ -777,7 +809,33 @@
 }
 
 
+/*!    Called when the team's CPU time clock which this timer refers to has 
been
+       set.
+
+       The caller must hold the scheduler lock.
+
+       \param changedBy The value by which the clock has changed.
+*/
 void
+ThreadTimeUserTimer::TimeWarped(bigtime_t changedBy)
+{
+       if (fThread == NULL || changedBy == 0)
+               return;
+
+       // If this is a relative timer, adjust fNextTime by the value the clock 
has
+       // changed.
+       if (!fAbsolute)
+               fNextTime += changedBy;
+
+       // reschedule the kernel timer
+       if (fScheduled) {
+               Stop();
+               Start();
+       }
+}
+
+
+void
 ThreadTimeUserTimer::HandleTimer()
 {
        UserTimer::HandleTimer();
@@ -1022,6 +1080,44 @@
 }
 
 
+/*!    Called when the CPU time clock of the given thread has been set.
+
+       The caller must hold the scheduler lock.
+
+       \param thread The thread whose CPU time clock has been set.
+       \param changedBy The value by which the CPU time clock has changed
+               (new = old + changedBy).
+*/
+static void
+thread_clock_changed(Thread* thread, bigtime_t changedBy)
+{
+       for (ThreadTimeUserTimerList::ConstIterator it
+                               = thread->CPUTimeUserTimerIterator();
+                       ThreadTimeUserTimer* timer = it.Next();) {
+               timer->TimeWarped(changedBy);
+       }
+}
+
+
+/*!    Called when the CPU time clock of the given team has been set.
+
+       The caller must hold the scheduler lock.
+
+       \param team The team whose CPU time clock has been set.
+       \param changedBy The value by which the CPU time clock has changed
+               (new = old + changedBy).
+*/
+static void
+team_clock_changed(Team* team, bigtime_t changedBy)
+{
+       for (TeamTimeUserTimerList::ConstIterator it
+                               = team->CPUTimeUserTimerIterator();
+                       TeamTimeUserTimer* timer = it.Next();) {
+               timer->TimeWarped(changedBy);
+       }
+}
+
+
 // #pragma mark - kernel private
 
 
@@ -1221,8 +1317,6 @@
 status_t
 _user_set_clock(clockid_t clockID, bigtime_t time)
 {
-       // TODO: Setting a clock should update absolute timers!
-
        switch (clockID) {
                case CLOCK_MONOTONIC:
                        return B_BAD_VALUE;
@@ -1239,7 +1333,10 @@
                {
                        Thread* thread = thread_get_current_thread();
                        InterruptsSpinLocker schedulerLocker(gSchedulerLock);
-                       thread->cpu_clock_offset += time - 
thread->CPUTime(false);
+                       bigtime_t diff = time - thread->CPUTime(false);
+                       thread->cpu_clock_offset += diff;
+
+                       thread_clock_changed(thread, diff);
                        return B_OK;
                }
 
@@ -1267,8 +1364,10 @@
 
                        // set the time offset
                        InterruptsSpinLocker schedulerLocker(gSchedulerLock);
-                       team->cpu_clock_offset += time - team->CPUTime(false);
+                       bigtime_t diff = time - team->CPUTime(false);
+                       team->cpu_clock_offset += diff;
 
+                       team_clock_changed(team, diff);
                        return B_OK;
                }
        }


Other related posts:

  • » [haiku-commits] r41937 - in haiku/branches/developer/bonefish/signals: headers/private/kernel src/system/kernel - ingo_weinhold