| Author |
Message |
|
|
Post subject: Basic timing question
Posted: Mar 31, 2008 - 03:36 PM
|
|
Active Member
Joined: Sep 19, 2007
Posts: 11
|
|
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);
} |
|
|
| |
|
|
|
 |
|
|
Post subject: RE: Basic timing question
Posted: Mar 31, 2008 - 03:59 PM
|
|
QNX Master
Joined: Sep 01, 2002
Posts: 2667
|
|
| Do you have a signal handler, if you don't then the thread will most probably terminate. |
|
|
| |
|
|
|
 |
|
|
Post subject: RE: Basic timing question
Posted: Mar 31, 2008 - 04:36 PM
|
|
Active Member
Joined: Sep 19, 2007
Posts: 11
|
|
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? |
|
|
| |
|
|
|
 |
|
|
Post subject:
Posted: Mar 31, 2008 - 07:17 PM
|
|
Senior Member
Joined: Mar 10, 2004
Posts: 512
|
|
AMC,
Instead of using signal handlers (which don't convey priority) I'd recommend using MsgRecieve in conjunction with your timer code like so:
Code:
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 |
Last edited by Tim on Apr 01, 2008 - 01:48 PM; edited 1 time in total
|
| |
|
|
|
 |
|
|
Post subject:
Posted: Mar 31, 2008 - 11:01 PM
|
|
QNX Master
Joined: Jul 11, 2002
Posts: 557
|
|
|
Tim wrote:
AMC,
Instead of using signal handlers (which don't convey priority) I'd recommend using MsgRecieve in conjunction with your timer code like so:
I concur completely. |
|
|
| |
|
|
|
 |
|
|
Post subject:
Posted: Apr 01, 2008 - 01:27 PM
|
|
New Member
Joined: Dec 12, 2007
Posts: 7
|
|
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? |
|
|
| |
|
|
|
 |
|
|
Post subject:
Posted: Apr 01, 2008 - 01:52 PM
|
|
Senior Member
Joined: Mar 10, 2004
Posts: 512
|
|
Solvarg,
Take a look at ClockCycles instead.
Tim |
|
|
| |
|
|
|
 |
|
|
Post subject:
Posted: Apr 01, 2008 - 04:48 PM
|
|
QNX Master
Joined: Jul 11, 2002
Posts: 557
|
|
|
solvarg wrote:
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?
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. |
|
|
| |
|
|
|
 |
|
|
Post subject:
Posted: Apr 02, 2008 - 06:15 AM
|
|
New Member
Joined: Dec 12, 2007
Posts: 7
|
|
Thank you for the answers. ClockCycles function works fine and I'll take a look at DS1287.
solvarg |
|
|
| |
|
|
|
 |
|
|
Post subject:
Posted: Apr 02, 2008 - 06:18 AM
|
|
QNX Master
Joined: Sep 01, 2002
Posts: 2667
|
|
| ClockCycles() ?? Aren't you talking about ClockPeriod() instead? |
|
|
| |
|
|
|
 |
|
|
Post subject:
Posted: Apr 02, 2008 - 07:59 AM
|
|
New Member
Joined: Dec 12, 2007
Posts: 7
|
|
Is ClockCycles() sooo bad, that I should be talking about ClockPeriod instead?  |
|
|
| |
|
|
|
 |
|
|
Post subject:
Posted: Apr 02, 2008 - 01:45 PM
|
|
Senior Member
Joined: Mar 10, 2004
Posts: 512
|
|
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 |
|
|
| |
|
|
|
 |
|
|
Post subject:
Posted: Apr 04, 2008 - 12:01 PM
|
|
Senior Member
Joined: Apr 07, 2005
Posts: 257
|
|
| 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. |
|
|
| |
|
|
|
 |
|
|
Post subject:
Posted: Apr 04, 2008 - 09:24 PM
|
|
QNX Master
Joined: Jul 11, 2002
Posts: 557
|
|
|
Thunderblade wrote:
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. |
|
|
| |
|
|
|
 |
|
|