usleep taking too much time, small test case included

In the program below, I’m trying to measure the time elapse between a call
to usleep(10); I’m always getting 2 millisecond, until I increase the usleep
to 1000. Then I get 3 millisecond. I have made the program at high priority
(63). It is running on a pentium 1.3Ghz with almost nothing else running.
Why doesn’t I get a elapse time more close to the usleep call i’m setting.
I know I can create a timer. But I’m porting a program that use this method
to wait for small period of time.

Thanks
Rejean Senecal




#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#include <signal.h>
#include <math.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sched.h>
#include <time.h>

// Time diff in millisecond
#define OC_DEBUG_DIFF_TIME(END,START)
((double(END.tv_sec-START.tv_sec)*1000.0)+(double(END.tv_nsec-START.tv_nsec)
/1000000.0))
using namespace std;

int main(int argc, char** argv) {

std::cout << “Hello, realtime!” << std::endl;

//--------------------------------------------------------------------
// Check priority and make ourself realtime via sched_fifo.
//--------------------------------------------------------------------

sched_param schedulerParams;

schedulerParams.sched_priority=-1;
if (sched_getparam(getpid(), &schedulerParams)!=0){
perror("Cannot Get scheduler parameters ");
}

schedulerParams.sched_priority=63;

if(sched_setscheduler(getpid(), SCHED_FIFO, &schedulerParams))
{
perror("Cannot Set scheduler parameters ");
exit(-1);
}

//--------------------------------------------------------------------

struct timespec before;
struct timespec end;
if (clock_gettime(CLOCK_REALTIME,&before)){
perror(“clock_gettime”);
}

usleep(10);
clock_gettime(CLOCK_REALTIME,&end);
cout << " time " << OC_DEBUG_DIFF_TIME(end,before) << endl << flush;

}

You may want to look at these technical articles

http://www.qnx.com/developers/articles/article_834_1.html

http://www.qnx.com/developers/articles/article_826_2.html


“Rejean Senecal” <rsenecal@oerlikon.ca-no-spam> wrote in message
news:cp9ssm$kas$1@inn.qnx.com

In the program below, I’m trying to measure the time elapse between a call
to usleep(10); I’m always getting 2 millisecond, until I increase the
usleep
to 1000. Then I get 3 millisecond. I have made the program at high
priority
(63). It is running on a pentium 1.3Ghz with almost nothing else running.
Why doesn’t I get a elapse time more close to the usleep call i’m setting.
I know I can create a timer. But I’m porting a program that use this
method
to wait for small period of time.

Thanks
Rejean Senecal




#include <stdio.h
#include <stdlib.h
#include <iostream.h
#include <signal.h
#include <math.h
#include <sys/mman.h
#include <unistd.h
#include <sched.h
#include <time.h

// Time diff in millisecond
#define OC_DEBUG_DIFF_TIME(END,START)
((double(END.tv_sec-START.tv_sec)*1000.0)+(double(END.tv_nsec-START.tv_nsec)
/1000000.0))
using namespace std;

int main(int argc, char** argv) {

std::cout << “Hello, realtime!” << std::endl;

//--------------------------------------------------------------------
// Check priority and make ourself realtime via sched_fifo.
//--------------------------------------------------------------------

sched_param schedulerParams;

schedulerParams.sched_priority=-1;
if (sched_getparam(getpid(), &schedulerParams)!=0){
perror("Cannot Get scheduler parameters ");
}

schedulerParams.sched_priority=63;

if(sched_setscheduler(getpid(), SCHED_FIFO, &schedulerParams))
{
perror("Cannot Set scheduler parameters ");
exit(-1);
}

//--------------------------------------------------------------------

struct timespec before;
struct timespec end;
if (clock_gettime(CLOCK_REALTIME,&before)){
perror(“clock_gettime”);
}

usleep(10);
clock_gettime(CLOCK_REALTIME,&end);
cout << " time " << OC_DEBUG_DIFF_TIME(end,before) << endl << flush;

}

The article say: " Since the calling of delay() is asynchronous with the
running of the clock interrupt, that means that we have to add one clock
tick to a relative delay to ensure the correct amount of time "

In resume, usleep() is useless with qnx, because it will never be precise.
(This is not the case with RTOS Timesys Linux). What about nanosleep(),
doest it follow same rule. So, is my only option is the use a timer_create,
but will “MsgReceivePulse ( chid, &pulse, sizeof( pulse ), NULL )” be also
rule by the 1ms (1 clock tick) ?
Thanks.


“Jason Clarke” <jclarke@qnx.com> wrote in message
news:cpa4ft$prf$1@inn.qnx.com

You may want to look at these technical articles

http://www.qnx.com/developers/articles/article_834_1.html

http://www.qnx.com/developers/articles/article_826_2.html


“Rejean Senecal” <> rsenecal@oerlikon.ca-no-spam> > wrote in message
news:cp9ssm$kas$> 1@inn.qnx.com> …
In the program below, I’m trying to measure the time elapse between a
call
to usleep(10); I’m always getting 2 millisecond, until I increase the
usleep
to 1000. Then I get 3 millisecond. I have made the program at high
priority
(63). It is running on a pentium 1.3Ghz with almost nothing else
running.
Why doesn’t I get a elapse time more close to the usleep call i’m
setting.
I know I can create a timer. But I’m porting a program that use this
method
to wait for small period of time.

Thanks
Rejean Senecal

\


#include <stdio.h
#include <stdlib.h
#include <iostream.h
#include <signal.h
#include <math.h
#include <sys/mman.h
#include <unistd.h
#include <sched.h
#include <time.h

// Time diff in millisecond
#define OC_DEBUG_DIFF_TIME(END,START)

((double(END.tv_sec-START.tv_sec)*1000.0)+(double(END.tv_nsec-START.tv_nsec)
/1000000.0))
using namespace std;

int main(int argc, char** argv) {

std::cout << “Hello, realtime!” << std::endl;

//--------------------------------------------------------------------
// Check priority and make ourself realtime via sched_fifo.

//--------------------------------------------------------------------

sched_param schedulerParams;

schedulerParams.sched_priority=-1;
if (sched_getparam(getpid(), &schedulerParams)!=0){
perror("Cannot Get scheduler parameters ");
}

schedulerParams.sched_priority=63;

if(sched_setscheduler(getpid(), SCHED_FIFO, &schedulerParams))
{
perror("Cannot Set scheduler parameters ");
exit(-1);
}


//--------------------------------------------------------------------

struct timespec before;
struct timespec end;
if (clock_gettime(CLOCK_REALTIME,&before)){
perror(“clock_gettime”);
}

usleep(10);
clock_gettime(CLOCK_REALTIME,&end);
cout << " time " << OC_DEBUG_DIFF_TIME(end,before) << endl << flush;

}
\

Two points.

  1. nanosleep() works by CPU spinning. So it will be accurate as long as it
    doesn’t get swapped out by a higher priority thread.

  2. Using any of the timer routines, you CAN set the ticksize to less than
    1 ms. You will still have the off by 1 error.

The issue is that if the OS can’t guarantee you EXACTLY x number of
timeslices, would you rather have a little less or a little more. QNX
gives you AT LEAST x timeslices. If less is OK for you, just subtract 1
from what you are asking for.


Rejean Senecal <rsenecal@oerlikon.ca-no-spam> wrote:
RS > The article say: " Since the calling of delay() is asynchronous with the
RS > running of the clock interrupt, that means that we have to add one clock
RS > tick to a relative delay to ensure the correct amount of time "

RS > In resume, usleep() is useless with qnx, because it will never be precise.
RS > (This is not the case with RTOS Timesys Linux). What about nanosleep(),
RS > doest it follow same rule. So, is my only option is the use a timer_create,
RS > but will “MsgReceivePulse ( chid, &pulse, sizeof( pulse ), NULL )” be also
RS > rule by the 1ms (1 clock tick) ?
RS > Thanks.

Rejean Senecal wrote:

The article say: " Since the calling of delay() is asynchronous with the
running of the clock interrupt, that means that we have to add one clock
tick to a relative delay to ensure the correct amount of time "

In resume, usleep() is useless with qnx, because it will never be precise.
(This is not the case with RTOS Timesys Linux). What about nanosleep(),

QNX could be more precise by keeping track of when precisely your program requested it’s delay and add that into the calculation of the timeout. This would result in your 10 usec requests responding in no more than 1010 usec assuming the default system tick rate of 1 kHz.

nanosleep() busy-waits, you get good but expensive results.

Another way is to build your own timer lib based on your very own programmable hardware. :slight_smile:


doest it follow same rule. So, is my only option is the use a timer_create,
but will “MsgReceivePulse ( chid, &pulse, sizeof( pulse ), NULL )” be also
rule by the 1ms (1 clock tick) ?
Thanks.

I would be more inclined to build my own lib that does the above method by hooking the system tick IRQ with InterruptAttachEvent() and use ClockCycles() to gauge the precision and increase the rate from the default of 1 kHz to say 10 kHz with ClockPeriod().

“Bill Caroselli” <qtps@earthlink.net> wrote in message
news:cpaetq$35d$2@inn.qnx.com

Two points.

  1. nanosleep() works by CPU spinning. So it will be accurate as long as
    it
    doesn’t get swapped out by a higher priority thread.

  2. Using any of the timer routines, you CAN set the ticksize to less than
    1 ms. You will still have the off by 1 error.

Off by 1 what (not by 1 ms I hope) ?


The issue is that if the OS can’t guarantee you EXACTLY x number of
timeslices, would you rather have a little less or a little more. QNX
gives you AT LEAST x timeslices. If less is OK for you, just subtract 1
from what you are asking for.


Rejean Senecal <> rsenecal@oerlikon.ca-no-spam> > wrote:
RS > The article say: " Since the calling of delay() is asynchronous with
the
RS > running of the clock interrupt, that means that we have to add one
clock
RS > tick to a relative delay to ensure the correct amount of time "

RS > In resume, usleep() is useless with qnx, because it will never be
precise.
RS > (This is not the case with RTOS Timesys Linux). What about
nanosleep(),
RS > doest it follow same rule. So, is my only option is the use a
timer_create,
RS > but will “MsgReceivePulse ( chid, &pulse, sizeof( pulse ), NULL )”
be also
RS > rule by the 1ms (1 clock tick) ?
RS > Thanks.

In article <cpaetq$35d$2@inn.qnx.com>, qtps@earthlink.net says…

Two points.

  1. nanosleep() works by CPU spinning. So it will be accurate as long as it
    doesn’t get swapped out by a higher priority thread.

No, nanosleep() doesn’t spin. nanospin() does. If you don’t call
nanospin_calibrate() explicitly, libc will do it for you on first call
nanospin(). And this very first time you won’t get precise time delay,
so calibrate explicitly. Although busy loop looks like overkill, it is
not in many cases. If you need very short delay (less then 1-2 ms) and
you don’t need these delays so often (say, once or twice per second),
nanospin() is your friend.

  1. Using any of the timer routines, you CAN set the ticksize to less than
    1 ms. You will still have the off by 1 error.

Using ClockPeriod() you can set system timer resolution as precise as 10
us. So, using usleep() or nanosleep() you will get required time period
plus 0-10 us. Small tick time is quite overkill for system, that’s why
you need follow your requirements and common sense - might be 100 us
would be precise enough for you.


The issue is that if the OS can’t guarantee you EXACTLY x number of
timeslices, would you rather have a little less or a little more. QNX
gives you AT LEAST x timeslices. If less is OK for you, just subtract 1
from what you are asking for.


Rejean Senecal <> rsenecal@oerlikon.ca-no-spam> > wrote:
RS > The article say: " Since the calling of delay() is asynchronous with the
RS > running of the clock interrupt, that means that we have to add one clock
RS > tick to a relative delay to ensure the correct amount of time "

RS > In resume, usleep() is useless with qnx, because it will never be precise.
RS > (This is not the case with RTOS Timesys Linux).

LOL. I can believe that if they do busy loop with disabled interrupts
(as it’s usually in Linux), but they just don’t tell you about it.

Eduard.

RS > What about nanosleep(),
RS > doest it follow same rule. So, is my only option is the use a timer_create,
RS > but will “MsgReceivePulse ( chid, &pulse, sizeof( pulse ), NULL )” be also
RS > rule by the 1ms (1 clock tick) ?
RS > Thanks.

Rejean Senecal wrote:

“Bill Caroselli” <> qtps@earthlink.net> > wrote in message
2. Using any of the timer routines, you CAN set the ticksize to less than
1 ms. You will still have the off by 1 error.


Off by 1 what (not by 1 ms I hope) ?

Yep, one system tick to be precise.


Evan

ed1k wrote:

In article <cpaetq$35d$> 2@inn.qnx.com> >, > qtps@earthlink.net > says…

  1. nanosleep() works by CPU spinning. So it will be accurate as long as it
    doesn’t get swapped out by a higher priority thread.


    No, nanosleep() doesn’t spin. nanospin() does. If you don’t call

Good catch.


RS > In resume, usleep() is useless with qnx, because it will never be precise.
RS > (This is not the case with RTOS Timesys Linux).


LOL. I can believe that if they do busy loop with disabled interrupts
(as it’s usually in Linux), but they just don’t tell you about it.

I heard that the BE had efficient timer hardware, presumably in the CPU, that BEOS reprogrammed to fire for each timeout as required.


Evan

So, to close the discussion.

There is no way QNX will give me a precise sleep of 10 us with any sleep
function call except with the spin() familly of function.
My only other choice, if I don’t want a busy wait, is to use an external
signal (hardware).

p.s
Why QNX event bother to have function like
“clock_nanosleep(CLOCK_REALTIME,TIMER_ABSTIME,&rqtp,NULL);.” when the best
resolution you will get (by deault) is 1 ms.
The opengroup say that clock_nanosleep is a high resolution sleep with
specifiable clock.

“Evan Hillas” <blarg@blarg.blarg> wrote in message
news:cpaf5d$45h$1@inn.qnx.com

nanosleep() busy-waits, you get good but expensive results.

Did you mean to say nanospin? Or am I not understanding something about
nanosleep? I thought it put the thread into an efficient blocked state.

Lisa Scanlan

Rejean Senecal <rsenecal@oerlikon.ca-no-spam> wrote:

RS > “Bill Caroselli” <qtps@earthlink.net> wrote in message
RS > news:cpaetq$35d$2@inn.qnx.com

  1. Using any of the timer routines, you CAN set the ticksize to less than
    1 ms. You will still have the off by 1 error.

RS > Off by 1 what (not by 1 ms I hope) ?

Timeslice. Whatever that is set to.

You seem disappointed in QNX. Are there other OSes that do what you want
without requiring additional hardware? Which ones and how do work?

Marty Doane
Siemens L&A

“Rejean Senecal” <rsenecal@oerlikon.ca-no-spam> wrote in message
news:cpc7qe$d76$1@inn.qnx.com

So, to close the discussion.

There is no way QNX will give me a precise sleep of 10 us with any sleep
function call except with the spin() familly of function.
My only other choice, if I don’t want a busy wait, is to use an external
signal (hardware).

p.s
Why QNX event bother to have function like
“clock_nanosleep(CLOCK_REALTIME,TIMER_ABSTIME,&rqtp,NULL);.” when the best
resolution you will get (by deault) is 1 ms.
The opengroup say that clock_nanosleep is a high resolution sleep with
specifiable clock.
\

Marty Doane wrote:

You seem disappointed in QNX. Are there other OSes that do what you want
without requiring additional hardware? Which ones and how do work?

BeOS can do it, so can the PalmOS 6 kernel (not surprising, given the
same people built both of them). There are also patches to the Linux
kernel to add highres timers (http://www.celinux.org). QNX takes the
traditional periodic timer approach for all timer based APIs, while
these other systems are setup to program a timer to fire dynamically as
new timeout requests are made in the system. So there is no overhead to
the timers if no one is asking for a timeout. They may or may not also
have periodic timers going for the kernel itself - Linux does, PalmOS 6
does not.

chris

Yes, TimeSys Linux, doest the following:
If a high priority thread do a sleep(20), the thread is simply reschedule
later, and you are guarante that this thread will become runnable when the
sleep expired. So, it is easy to make (in my case) a communication thread,
on old hardware, that do the following.

ReadAsync(buffer,RADAR); //
usleep(100); // Wait for DMA to complete
WriteAsynch(buffer,TARGET_TRAKER)
usleep(300); // Wait for the device to complete is task
ReadAsync(buffer,TARGET_TRAKER); //
usleep(50); // Wait for DMA to comple
WriteAsynch(buffer,SYMBOLOGY_CONSOLE);


I was considering porting the code on QNX, until I realize I was getting 1
ms delay between each sleep call.
Is it just me, when I wrote usleep(100), in a REALTIME OS. I expect to have
some additionnal delay in an order of magnitude (10 times) less than the
value i wrote. If usleep(100) give me 110us delay, I won’t conplain. In my
mind that why there are, sleep(), usleep() and nanosleep();



“Marty Doane” <martin.doane@siemens.com> wrote in message
news:cpco5r$obk$1@inn.qnx.com

You seem disappointed in QNX. Are there other OSes that do what you want
without requiring additional hardware? Which ones and how do work?

Marty Doane
Siemens L&A

“Rejean Senecal” <> rsenecal@oerlikon.ca-no-spam> > wrote in message
news:cpc7qe$d76$> 1@inn.qnx.com> …
So, to close the discussion.

There is no way QNX will give me a precise sleep of 10 us with any sleep
function call except with the spin() familly of function.
My only other choice, if I don’t want a busy wait, is to use an external
signal (hardware).

p.s
Why QNX event bother to have function like
“clock_nanosleep(CLOCK_REALTIME,TIMER_ABSTIME,&rqtp,NULL);.” when the
best
resolution you will get (by deault) is 1 ms.
The opengroup say that clock_nanosleep is a high resolution sleep with
specifiable clock.


\

In article <cpd532$44p$1@inn.qnx.com>, rsenecal@oerlikon.ca-no-spam
says…

Yes, TimeSys Linux, doest the following:
If a high priority thread do a sleep(20), the thread is simply reschedule
later, and you are guarante that this thread will become runnable when the
sleep expired. So, it is easy to make (in my case) a communication thread,
on old hardware, that do the following.

ReadAsync(buffer,RADAR); //
usleep(100); // Wait for DMA to complete
WriteAsynch(buffer,TARGET_TRAKER)
usleep(300); // Wait for the device to complete is task
ReadAsync(buffer,TARGET_TRAKER); //
usleep(50); // Wait for DMA to comple
WriteAsynch(buffer,SYMBOLOGY_CONSOLE);

You can wait for DMA to complete in nanospin() loop. Anyway system bus
will become busy, so no one can effectively run. nanospin() doesn’t
affect interrupts and their latency so dramaticaly as small ticksize
does.

I was considering porting the code on QNX, until I realize I was getting 1
ms delay between each sleep call.
Is it just me, when I wrote usleep(100), in a REALTIME OS. I expect to have
some additionnal delay in an order of magnitude (10 times) less than the
value i wrote. If usleep(100) give me 110us delay, I won’t conplain. In my
mind that why there are, sleep(), usleep() and nanosleep();

You can do that, use ClockPeriod() to set ticksize 10 us. Continuing
your thought one may want to sleep for 10 millisecond and wouldn’t mind
to be waken up after 11 ms.

Eduard.

“Marty Doane” <> martin.doane@siemens.com> > wrote in message
news:cpco5r$obk$> 1@inn.qnx.com> …
You seem disappointed in QNX. Are there other OSes that do what you want
without requiring additional hardware? Which ones and how do work?

Marty Doane
Siemens L&A

“Rejean Senecal” <> rsenecal@oerlikon.ca-no-spam> > wrote in message
news:cpc7qe$d76$> 1@inn.qnx.com> …
So, to close the discussion.

There is no way QNX will give me a precise sleep of 10 us with any sleep
function call except with the spin() familly of function.
My only other choice, if I don’t want a busy wait, is to use an external
signal (hardware).

p.s
Why QNX event bother to have function like
“clock_nanosleep(CLOCK_REALTIME,TIMER_ABSTIME,&rqtp,NULL);.” when the
best
resolution you will get (by deault) is 1 ms.
The opengroup say that clock_nanosleep is a high resolution sleep with
specifiable clock.





\

It does look like you should be using nanospin_ns().

On an aside, DMA is much better managed via interrupts.

Lisa Scanlan wrote:

Did you mean to say nanospin? Or am I not understanding something about
nanosleep? I thought it put the thread into an efficient blocked state.

Yep, ed1k already pulled us up on that one. :slight_smile:

Chris McKillop wrote:

Marty Doane wrote:

You seem disappointed in QNX. Are there other OSes that do what you want
without requiring additional hardware? Which ones and how do work?


BeOS can do it, so can the PalmOS 6 kernel (not surprising, given the

That’s not very desirable on common PC hardware due to amount of PCI bus time needed to adjust the timer. The APIC in some server x86 setups has the required hardware built right into the CPU, this is exactly what is needed to efficiently do dynamic timeouts.


same people built both of them). There are also patches to the Linux
kernel to add highres timers (> http://www.celinux.org> ). QNX takes the

What they might be doing here is having a high-res system tick but only servicing the full system lists at the usual 10 msecs. And even staggering them to smooth out the processing burden.


Evan

Chris McKillop wrote:

BeOS can do it, so can the PalmOS 6 kernel (not surprising, given the
same people built both of them). There are also patches to the Linux

Looking up me dusty copy of Motorola’s PPC601 reference book from 1993 there is a “decrementer” register that generates an interrupt every time it crosses zero. This will be what inspired the BEOS author to do this method. I presume newer ARMs have this feature too. :slight_smile: