use clock_gettime for internal timers instead of gettimeofday .. so now our
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Wed, 16 Apr 2008 09:53:18 +0000 (09:53 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Wed, 16 Apr 2008 09:53:18 +0000 (09:53 +0000)
timers are independent of the normal linux clock (and change linux time
without inform e2 is now really uncritical)

lib/base/ebase.cpp
lib/base/ebase.h
lib/dvb/dvbtime.cpp
main/Makefile.am

index 01ee6a5386fc3a4a74d77d00e92ba6a37af6b1ae..038e5ad1dfda05ed0d5d3c674f71b9223996cc35 100644 (file)
@@ -44,11 +44,10 @@ void eTimer::start(long msek, bool singleShot)
        bActive = true;
        bSingleShot = singleShot;
        interval = msek;
-       gettimeofday(&nextActivation, 0);
-       nextActivation.tv_sec -= context.getTimeOffset();
-//     eDebug("this = %p\nnow sec = %d, usec = %d\nadd %d msec", this, nextActivation.tv_sec, nextActivation.tv_usec, msek);
+       clock_gettime(CLOCK_MONOTONIC, &nextActivation);
+//     eDebug("this = %p\nnow sec = %d, nsec = %d\nadd %d msec", this, nextActivation.tv_sec, nextActivation.tv_nsec, msek);
        nextActivation += (msek<0 ? 0 : msek);
-//     eDebug("next Activation sec = %d, usec = %d", nextActivation.tv_sec, nextActivation.tv_usec );
+//     eDebug("next Activation sec = %d, nsec = %d", nextActivation.tv_sec, nextActivation.tv_nsec );
        context.addTimer(this);
 }
 
@@ -59,12 +58,11 @@ void eTimer::startLongTimer( int seconds )
 
        bActive = bSingleShot = true;
        interval = 0;
-       gettimeofday(&nextActivation, 0);
-       nextActivation.tv_sec -= context.getTimeOffset();
-//     eDebug("this = %p\nnow sec = %d, usec = %d\nadd %d sec", this, nextActivation.tv_sec, nextActivation.tv_usec, seconds);
+       clock_gettime(CLOCK_MONOTONIC, &nextActivation);
+//     eDebug("this = %p\nnow sec = %d, nsec = %d\nadd %d sec", this, nextActivation.tv_sec, nextActivation.tv_nsec, seconds);
        if ( seconds > 0 )
                nextActivation.tv_sec += seconds;
-//     eDebug("next Activation sec = %d, usec = %d", nextActivation.tv_sec, nextActivation.tv_usec );
+//     eDebug("next Activation sec = %d, nsec = %d", nextActivation.tv_sec, nextActivation.tv_nsec );
        context.addTimer(this);
 }
 
@@ -108,18 +106,12 @@ void eTimer::activate()   // Internal Funktion... called from eApplication
        /*emit*/ timeout();
 }
 
-void eTimer::addTimeOffset( int offset )
-{
-       nextActivation.tv_sec += offset;
-}
-
 // mainloop
 ePtrList<eMainloop> eMainloop::existing_loops;
 
 eMainloop::~eMainloop()
 {
        existing_loops.remove(this);
-       pthread_mutex_destroy(&recalcLock);
        for (std::map<int, eSocketNotifier*>::iterator it(notifiers.begin());it != notifiers.end();++it)
                it->second->stop();
        while(m_timer_list.begin() != m_timer_list.end())
@@ -157,15 +149,11 @@ int eMainloop::processOneEvent(unsigned int twisted_timeout, PyObject **res, ePy
 
        if (!m_timer_list.empty() || twisted_timeout > 0)
        {
-               applyTimeOffset();
                if (!m_timer_list.empty())
                {
                        /* process all timers which are ready. first remove them out of the list. */
                        while (!m_timer_list.empty() && (poll_timeout = timeout_usec( m_timer_list.begin()->getNextActivation() ) ) <= 0 )
-                       {
                                m_timer_list.begin()->activate();
-                               applyTimeOffset();
-                       }
                        if (poll_timeout < 0)
                                poll_timeout = 0;
                        else /* convert us to ms */
@@ -216,7 +204,7 @@ int eMainloop::processOneEvent(unsigned int twisted_timeout, PyObject **res, ePy
                Py_END_ALLOW_THREADS
        } else
                ret = ::poll(pfd, fdcount, poll_timeout);
-       
+
        m_is_idle = 0;
 
                        /* ret > 0 means that there are some active poll entries. */
@@ -283,7 +271,7 @@ int eMainloop::iterate(unsigned int twisted_timeout, PyObject **res, ePyObject d
 
        if (twisted_timeout)
        {
-               gettimeofday(&m_twisted_timer, 0);
+               clock_gettime(CLOCK_MONOTONIC, &m_twisted_timer);
                m_twisted_timer += twisted_timeout;
        }
 
@@ -302,15 +290,12 @@ int eMainloop::iterate(unsigned int twisted_timeout, PyObject **res, ePyObject d
                int to = 0;
                if (twisted_timeout)
                {
-                       timeval now, timeout;
-                       gettimeofday(&now, 0);
-                       m_twisted_timer += time_offset;  // apply pending offset
+                       timespec now, timeout;
+                       clock_gettime(CLOCK_MONOTONIC, &now);
                        if (m_twisted_timer<=now) // timeout
                                return 0;
                        timeout = m_twisted_timer - now;
-                       to = timeout.tv_sec * 1000 + timeout.tv_usec / 1000;
-                       // remove pending offset .. it is re-applied in next call of processOneEvent.. applyTimeOffset
-                       m_twisted_timer -= time_offset;  
+                       to = timeout.tv_sec * 1000 + timeout.tv_nsec / 1000000;
                }
                ret = processOneEvent(to, res, dict);
        } while ( !ret && !(res && *res) );
@@ -357,38 +342,6 @@ void eMainloop::quit(int ret)
        app_quit_now = true;
 }
 
-void eMainloop::addTimeOffset(int offset)
-{
-       for (ePtrList<eMainloop>::iterator it(existing_loops.begin()); it != existing_loops.end(); ++it )
-               it->addInstanceTimeOffset(offset);
-}
-
-void eMainloop::addInstanceTimeOffset(int offset)
-{
-       singleLock s(recalcLock);
-       if (m_timer_list.empty())
-               time_offset=0;
-       else
-       {
-               if ( time_offset )
-                       eDebug("time_offset %d avail.. add new offset %d than new is %d",
-                       time_offset, offset, time_offset+offset);
-               time_offset+=offset;
-       }
-}
-
-void eMainloop::applyTimeOffset()
-{
-       singleLock s(recalcLock);
-       if ( time_offset )
-       {
-               for (ePtrList<eTimer>::iterator it(m_timer_list.begin()); it != m_timer_list.end(); ++it )
-                       it->addTimeOffset( time_offset );
-               m_twisted_timer += time_offset;
-               time_offset=0;
-       }
-}
-
 eApplication* eApp = 0;
 
 #include "structmember.h"
index c4dab6216f549ea38104754dd3872a34d56e67a4..10b46120a3e7737033f2756d468e36c8eb597e8f 100644 (file)
@@ -21,115 +21,115 @@ extern eApplication* eApp;
 
 #ifndef SWIG
        /* TODO: remove these inlines. */
-static inline bool operator<( const timeval &t1, const timeval &t2 )
+static inline bool operator<( const timespec &t1, const timespec &t2 )
 {
-       return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec);
+       return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_nsec < t2.tv_nsec);
 }
 
-static inline bool operator<=( const timeval &t1, const timeval &t2 )
+static inline bool operator<=( const timespec &t1, const timespec &t2 )
 {
-       return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_usec <= t2.tv_usec);
+       return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_nsec <= t2.tv_nsec);
 }
 
-static inline timeval &operator+=( timeval &t1, const timeval &t2 )
+static inline timespec &operator+=( timespec &t1, const timespec &t2 )
 {
        t1.tv_sec += t2.tv_sec;
-       if ( (t1.tv_usec += t2.tv_usec) >= 1000000 )
+       if ( (t1.tv_nsec += t2.tv_nsec) >= 1000000000 )
        {
                t1.tv_sec++;
-               t1.tv_usec -= 1000000;
+               t1.tv_nsec -= 1000000000;
        }
        return t1;
 }
 
-static inline timeval operator+( const timeval &t1, const timeval &t2 )
+static inline timespec operator+( const timespec &t1, const timespec &t2 )
 {
-       timeval tmp;
+       timespec tmp;
        tmp.tv_sec = t1.tv_sec + t2.tv_sec;
-       if ( (tmp.tv_usec = t1.tv_usec + t2.tv_usec) >= 1000000 )
+       if ( (tmp.tv_nsec = t1.tv_nsec + t2.tv_nsec) >= 1000000000 )
        {
                tmp.tv_sec++;
-               tmp.tv_usec -= 1000000;
+               tmp.tv_nsec -= 1000000000;
        }
        return tmp;
 }
 
-static inline timeval operator-( const timeval &t1, const timeval &t2 )
+static inline timespec operator-( const timespec &t1, const timespec &t2 )
 {
-       timeval tmp;
+       timespec tmp;
        tmp.tv_sec = t1.tv_sec - t2.tv_sec;
-       if ( (tmp.tv_usec = t1.tv_usec - t2.tv_usec) < 0 )
+       if ( (tmp.tv_nsec = t1.tv_nsec - t2.tv_nsec) < 0 )
        {
                tmp.tv_sec--;
-               tmp.tv_usec += 1000000;
+               tmp.tv_nsec += 1000000000;
        }
        return tmp;
 }
 
-static inline timeval operator-=( timeval &t1, const timeval &t2 )
+static inline timespec operator-=( timespec &t1, const timespec &t2 )
 {
        t1.tv_sec -= t2.tv_sec;
-       if ( (t1.tv_usec -= t2.tv_usec) < 0 )
+       if ( (t1.tv_nsec -= t2.tv_nsec) < 0 )
        {
                t1.tv_sec--;
-               t1.tv_usec += 1000000;
+               t1.tv_nsec += 1000000000;
        }
        return t1;
 }
 
-static inline timeval &operator+=( timeval &t1, const long msek )
+static inline timespec &operator+=( timespec &t1, const long msek )
 {
        t1.tv_sec += msek / 1000;
-       if ( (t1.tv_usec += (msek % 1000) * 1000) >= 1000000 )
+       if ( (t1.tv_nsec += (msek % 1000) * 1000000) >= 1000000000 )
        {
                t1.tv_sec++;
-               t1.tv_usec -= 1000000;
+               t1.tv_nsec -= 1000000000;
        }
        return t1;
 }
 
-static inline timeval operator+( const timeval &t1, const long msek )
+static inline timespec operator+( const timespec &t1, const long msek )
 {
-       timeval tmp;
+       timespec tmp;
        tmp.tv_sec = t1.tv_sec + msek / 1000;
-       if ( (tmp.tv_usec = t1.tv_usec + (msek % 1000) * 1000) >= 1000000 )
+       if ( (tmp.tv_nsec = t1.tv_nsec + (msek % 1000) * 1000000) >= 1000000000 )
        {
                tmp.tv_sec++;
-               tmp.tv_usec -= 1000000;
+               tmp.tv_nsec -= 1000000;
        }
        return tmp;
 }
 
-static inline timeval operator-( const timeval &t1, const long msek )
+static inline timespec operator-( const timespec &t1, const long msek )
 {
-       timeval tmp;
+       timespec tmp;
        tmp.tv_sec = t1.tv_sec - msek / 1000;
-       if ( (tmp.tv_usec = t1.tv_usec - (msek % 1000)*1000) < 0 )
+       if ( (tmp.tv_nsec = t1.tv_nsec - (msek % 1000)*1000000) < 0 )
        {
                tmp.tv_sec--;
-               tmp.tv_usec += 1000000;
+               tmp.tv_nsec += 1000000000;
        }
        return tmp;
 }
 
-static inline timeval operator-=( timeval &t1, const long msek )
+static inline timespec operator-=( timespec &t1, const long msek )
 {
        t1.tv_sec -= msek / 1000;
-       if ( (t1.tv_usec -= (msek % 1000) * 1000) < 0 )
+       if ( (t1.tv_nsec -= (msek % 1000) * 1000000) < 0 )
        {
                t1.tv_sec--;
-               t1.tv_usec += 1000000;
+               t1.tv_nsec += 1000000000;
        }
        return t1;
 }
 
-static inline long timeout_usec ( const timeval & orig )
+static inline long timeout_usec ( const timespec & orig )
 {
-       timeval now;
-       gettimeofday(&now,0);
+       timespec now;
+       clock_gettime(CLOCK_MONOTONIC, &now);
        if ( (orig-now).tv_sec > 2000 )
                return 2000*1000*1000;
-       return (orig-now).tv_sec*1000000 + (orig-now).tv_usec;
+       return (orig-now).tv_sec*1000000 + (orig-now).tv_nsec/1000;
 }
 
 class eMainloop;
@@ -190,23 +190,16 @@ class eMainloop
        int loop_level;
        int processOneEvent(unsigned int user_timeout, PyObject **res=0, ePyObject additional=ePyObject());
        int retval;
-       int time_offset;
        int m_is_idle;
-       pthread_mutex_t recalcLock;
-       
+
        int m_interrupt_requested;
-       timeval m_twisted_timer; // twisted timer
-       
+       timespec m_twisted_timer; // twisted timer
+
        void addSocketNotifier(eSocketNotifier *sn);
        void removeSocketNotifier(eSocketNotifier *sn);
        void addTimer(eTimer* e);
        void removeTimer(eTimer* e);
-       void applyTimeOffset();
 public:
-       static void addTimeOffset(int offset);
-       void addInstanceTimeOffset(int offset);
-       int getTimeOffset() { return time_offset; }
-
 #ifndef SWIG
        static ePtrList<eMainloop> existing_loops;
 #endif
@@ -215,7 +208,6 @@ public:
                :app_quit_now(0),loop_level(0),retval(0), m_is_idle(0), m_interrupt_requested(0)
        {
                existing_loops.push_back(this);
-               pthread_mutex_init(&recalcLock, 0);
        }
        virtual ~eMainloop();
 
@@ -235,12 +227,12 @@ public:
                /* run will iterate endlessly until the app is quit, and return
                   the exit code */
        int runLoop();
-       
+
                /* our new shared polling interface. */
        PyObject *poll(SWIG_PYOBJECT(ePyObject) dict, SWIG_PYOBJECT(ePyObject) timeout);
        void interruptPoll();
        void reset();
-       
+
                /* m_is_idle needs to be atomic, but it doesn't really matter much, as it's read-only from outside */
        int isIdle() { return m_is_idle; }
 };
@@ -276,11 +268,10 @@ class eTimer
 {
        friend class eMainloop;
        eMainloop &context;
-       timeval nextActivation;
+       timespec nextActivation;
        long interval;
        bool bSingleShot;
        bool bActive;
-       void addTimeOffset(int);
        void activate();
 public:
        /**
@@ -296,7 +287,7 @@ public:
 
        bool isActive() { return bActive; }
 
-       timeval &getNextActivation() { return nextActivation; }
+       timespec &getNextActivation() { return nextActivation; }
 
        void start(long msec, bool b=false);
        void stop();
index 7684bfa4b3fe3407eeb9203b1b2fc062bda96d94..9272462a23e12cd608578b95f0d99205cd5b666a 100644 (file)
@@ -221,14 +221,13 @@ void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan, int up
                                        now.tm_sec);
                                m_time_difference = rtc_time - linuxTime;
                                eDebug("[eDVBLocalTimerHandler] RTC to Receiver time difference is %ld seconds", nowTime - rtc_time );
-                               if ( abs(m_time_difference) > 59 )
+                               if ( m_time_difference )
                                {
                                        eDebug("[eDVBLocalTimerHandler] set Linux Time to RTC Time");
                                        timeval tnow;
                                        gettimeofday(&tnow,0);
                                        tnow.tv_sec=rtc_time;
                                        settimeofday(&tnow,0);
-                                       eMainloop::addTimeOffset(m_time_difference);
                                        m_time_difference=0;
                                }
                                else if ( !m_time_difference )
@@ -352,14 +351,13 @@ void eDVBLocalTimeHandler::updateTime( time_t tp_time, eDVBChannel *chan, int up
                else
                        eDebug("[eDVBLocalTimerHandler] don't update RTC");
 
-               if ( abs(m_time_difference) > 59 )
+               if ( m_time_difference )
                {
                        eDebug("[eDVBLocalTimerHandler] set Linux Time");
                        timeval tnow;
                        gettimeofday(&tnow,0);
                        tnow.tv_sec=t;
                        settimeofday(&tnow,0);
-                       eMainloop::addTimeOffset(m_time_difference);
                        m_time_difference=0;
                }
 
index 9b917b783f9554361cb5ff010894d78020d8388a..67d84660b5409d3fef8f61ea831fe260ff9e5ca0 100644 (file)
@@ -52,7 +52,7 @@ enigma2_LDADD = \
        @LIBUNGIF_LIBS@ \
        @XML2_LIBS@ \
        @XMLCCWRAP_LIBS@ \
-       -ldl -lpthread -lcrypt -lresolv
+       -ldl -lpthread -lcrypt -lresolv -lrt
 
 enigma2$(EXEEXT): $(enigma2_OBJECTS) $(enigma2_DEPENDENCIES) $(enigma2_LDADD_WHOLE)
 #      @rm -f enigma2$(EXEEXT)