Page 1 of 1

"Interval Timer" - regular awaking of a Working Th

Posted: Mon Mar 21, 2005 5:29 pm
by NicolasC
Hi all,

I would need to wake up one of the working thread of the Core of my application very regularly.

To that aim, in a previous non-multiplateform version of my Core (on Linux), I used the "real time" interval timers (timer_create, timer_settime, etc. API, -lrt ) and signals (sigwait()). Well, it was OK. However, interval timers are not really portable...

For porting it to multiplatgeform, I may use wxThread::Sleep(int ms), that is : request the current time, and deduce the amount of millisecond to wait for.
However, this would not be very satisfying, because I need as-accurate-as-possible timing (requesting time and computing the time to wait for may introduce a bias), and sometimes very quick loops (one event each 10ms).
Something like interval timers (or better : condititions, or semaphores, that would be 'posted' on a regular time basis) would be much better, I guess.

wxTimers are only for the main thread (ie : the event loop thread), so that they are unuseful in my case.

What would you advice to awake my working thread regularly ?

Thx !
Nicolas

Posted: Thu Mar 24, 2005 1:35 pm
by NicolasC
I reply to myself, in case it could be useful for somebody else.
So far, the best I found is to :
- set up a thread dedicated to the generation of regular "events"
- get the current time, store it as 'next event time' (wxDateTime::Now())
Then, in a loop :
{
- add the timer time to the 'next event time'
- get the current time, and compute the number of millisecond to wait until the 'next event time'
- sleep the process this number of millisecond
- send the 'event'
]

In the following code, I use :
- wxSemaphore::WaitTimeout to sleep the processs (so that, if needed, I can easily wake it up externally by Posting the semaphore)
- another semaphore to 'send the timer event'
The code shows only the thread routine.

Code: Select all



#define INTERVAL_TIMER_TIME_MS 20

// routine of the thread that emulate a pseudo interval timer 
void IntervalTimerEmulation_routine(void *data) {
    wxSemaphore timerSemaphore;
    nextSynchroTime=wxDateTime::Now()+wxTimeSpan(0,0,0,synchro_ms);

    // Loop. Should feature a way to stop the thread, according to the needs 
    while(1) {
         long  toWait = (nextSynchroTime-wxDateTime::Now()) .GetMilliseconds(). ToLong();
         timerSemaphore.WaitTimeout(toWait);

       // send the "event". I use here a semaphore
       // eventSemaphore is a semaphore declared elsewhere, 
       // and Waited by the process that has to be time-regulated
        if(eventSemaphore->Post() != 0){
          perror("PositionFlowProcess_C::synchroThreadWork post semSynchro");
        }
        nextSynchroTime+=wxTimeSpan(0,0,0,synchro_ms);
    }
    pthread_exit(NULL);
}
Well, this is the best I found so far :=)