Basic timing question

I am working with several threads that need to operate at different frequencies (nothing very fast now, up to a couple of hundred Hz). I would like to put each thread to sleep and wake it up at its specified interval.

I am currently trying this by creating a timer that sends a signal at a fixed interval. I am putting the thread to sleep fine, but I cant get the timer to signal the thread to wake up. Is this possible or am I just doing something wrong? Or is there a better method to do this? (I tried interrupts awhile back, but was having problems with the different signals returned from the interrupt waking up all the threads) Any help/suggestions/links would be greatly appreciated.

Thanks,
AM

Here’s the thread code:

void * tx_thread(void *arg)
{
struct sigevent event;
struct itimerspec itime;
timer_t timer_id;

event.sigev_notify = SIGEV_SIGNAL_THREAD;
event.sigev_priority = getprio(0);
event.sigev_code = 3;
timer_create(CLOCK_REALTIME, &event, &timer_id);

// SIGEV_SIGNAL_THREAD_INIT( &event, 0, 0, 0);

itime.it_value.tv_sec = 0;
itime.it_value.tv_nsec = 250000000; 
itime.it_interval.tv_sec = 0;
itime.it_interval.tv_nsec = 250000000; 
timer_settime(timer_id, 0, &itime, NULL);

while (1)
{
	sleep(3);	//3 sec timeout, if nothing wakes thread
                    //STUFF DONE HERE
                    //thread functionality removed since its irrelevant to timer & sleep
}
pthread_exit(NULL);

}

Do you have a signal handler, if you don’t then the thread will most probably terminate.

No, I havent used a signal handler. I’ll read up on signal handlers, as I havent used them before. But, the sleep command just times out and the thread continues to loop within the while section. Any basic suggestions/examples for signal handlers?

As a work around, I can put all the threads to sleep for fixed intervals and let the sleep timeout wake the thread and control the frequency. But, as the thread code progresses, the execution time may change and thus the frequency. This is why I’d like to have something clock based that regularly wakes threads, mostly independent of thread complexity. Is using the sleep command, signal handlers and/or timers a good way to get somewhat regular timing?

AMC,

Instead of using signal handlers (which don’t convey priority) I’d recommend using MsgRecieve in conjunction with your timer code like so:


struct Message
{
    // This structure contains timer events.
    struct _pulse timerPulse;
};

void * tx_thread(void *arg) 
{ 
int channelId
int userId = 0;
int receiveId;
struct sigevent event; 
struct itimerspec itime; 
timer_t timer_id; 
Message msg;

// Create a channel
channelId = ChannelCreate(0);

// Set up the timer event parameters for the O/S. The timer will deliver
// the user id when it expires. You can change the userId if you have
// one thread handling multiple timers. If you have 1 timer per thread
// then leave it as 0.
SIGEV_PULSE_INIT(&event, ConnectAttach(ND_LOCAL_NODE, 0, channelId, _NTO_SIDE_CHANNEL, 0), SIGEV_PULSE_PRIO_INHERIT, 0, userId);
timer_create(CLOCK_REALTIME, &event, &timer_id); 
 

itime.it_value.tv_sec = 0; 
itime.it_value.tv_nsec = 250000000; 
itime.it_interval.tv_sec = 0; 
itime.it_interval.tv_nsec = 250000000; 
timer_settime(timer_id, 0, &itime, NULL); 

while (1) 
{ 
// Wait till the timer expires.
if ((MsgReceive(channelId, &msg, sizeof(Message), NULL)) < 0)
{
    printf ("error\n");
}
else
{
    // We got our timer. In the case of multiple timers you have to check the
    // userId contained in msg.timerPulse to know which you got. If you are 
    // receiving messages from  other threads there is a lot other code that 
    // has to go here. If you are just getting a single timer this is all you 
    // need.
    //STUFF DONE HERE 
    //thread functionality removed since its irrelevant to timer & sleep 
} 
pthread_exit(NULL); 
} 

Tim

I concur completely.

If I would like to generate pulses faster than one milisecond (for example 0.5ms), is there a way to test if that I actually get that value?
I tried to do work with clock_gettime or gettimeofday but when I try to use them like:

clock_gettime(CLOCK_REALTIME,&t_start);
clock_gettime(CLOCK_REALTIME,&t_finish);
tt =(double)(t_finish.tv_nsec - t_start.tv_nsec);
while(tt<500000)
{
clock_gettime(CLOCK_REALTIME,&t_finish);
tt =(double)(t_finish.tv_nsec - t_start.tv_nsec);
}

I can’t get values below 1000000ns. Inside the loop I have zeros and when it is done I suddenly get 1000000ns.
Is this a wrong way to use them?

Solvarg,

Take a look at ClockCycles instead.

Tim

Yes, although you will need to either:

a) change the ticksize (typically a command line arg to startup), but this is not recommended, since you are causing the clock handler (which does a fair amount of work unrelated to your application) to run more frequently.

b) setup another programmable timer interrupt just for your own applications use. On the x86 you can use the DS1287 interface (chip doesn’t exist anymore but there is an emulation for it). This is the preferred method.

Thank you for the answers. ClockCycles function works fine and I’ll take a look at DS1287.

solvarg

ClockCycles() ?? Aren’t you talking about ClockPeriod() instead?

Is ClockCycles() sooo bad, that I should be talking about ClockPeriod instead? :slight_smile:

Solvarg,

ClockPeriod can be used to adjust the tick size (option A) that rgallen mentioned.

ClockCycles is used to for taking timestamps using very small differences (as you discovered already).

Tim

IMHO generally it’s a bad idea to use software timers for things that operate in the <10ms area. It may work, but latencies are normal because it’s just a software-based timer that is counted ‘by hand’ every tick. Making the tick faster isn’t the best idea either, because it slows down the rest of the system. A hardware based timer is the best choice. And yes, pulses are much better than signals in case you want to explicitly wait on them anyway.

Yup, and under-the-covers a signal is actually implemented using the identical mechanism as a pulse (a QNX sigevent), so efficiency-wise they are identical.