Hi Eric,
On 2012-06-14 Eric Norum wrote:
> Well -- do all architectures provide float.h?
Yes, that's in ANSI C89 which everything supports.
> If so, then:
> void epicsThreadSleep(double seconds)
> {
> STATUS status;
> int ticks;
>
> if (seconds <= 0.0) {
> ticks = 0;
> } else {
> ticks = (seconds * sysClkRateGet()) + (1.0 - DBL_EPSILON);
> }
> status = taskDelay(ticks);
> if (status) errlogPrintf("epicsThreadSleep\n");
> }
I thought that would work, but it adds an extra tick to longer delays. Sorry,
my bad for suggesting it. With sysClkRate = 60 it actually gives:
delay = 0.000 => ticks = 0
delay = 0.001 => ticks = 1
delay = 0.010 => ticks = 1
delay = 0.100 => ticks = 7
delay = 1.000 => ticks = 61
delay = 10.000 => ticks = 601
delay = 100.000 => ticks = 6001
> But I think that:
> void epicsThreadSleep(double seconds)
> {
> STATUS status;
> int ticks;
>
> if (seconds <= 0.0) {
> ticks = 0;
> } else {
> ticks = (seconds * sysClkRateGet()) + 0.999999;
> }
> status = taskDelay(ticks);
> if (status) errlogPrintf("epicsThreadSleep\n");
> }
>
> is just as good.
Lets go with 0.999999999, chosen since we only represent time down to the
nanosecond anyway.
Original algorithm
request = 0.000000000 => ticks = 0, error = 0.000000000
request = 0.000000001 => ticks = 1, error = 0.016666666
request = 0.000001000 => ticks = 1, error = 0.016665667
request = 0.001000000 => ticks = 1, error = 0.015666667
request = 0.010000000 => ticks = 1, error = 0.006666667
request = 0.016666667 => ticks = 1, error = 0.000000000
request = 0.020000000 => ticks = 1, error = -0.003333333
request = 0.030000000 => ticks = 2, error = 0.003333333
request = 0.033333333 => ticks = 2, error = 0.000000000
request = 0.040000000 => ticks = 2, error = -0.006666667
request = 0.050000000 => ticks = 3, error = 0.000000000
request = 0.060000000 => ticks = 4, error = 0.006666667
request = 0.070000000 => ticks = 4, error = -0.003333333
request = 0.080000000 => ticks = 5, error = 0.003333333
request = 0.090000000 => ticks = 5, error = -0.006666667
request = 0.100000000 => ticks = 6, error = 0.000000000
request = 0.166666667 => ticks = 10, error = 0.000000000
request = 0.200000000 => ticks = 12, error = 0.000000000
request = 0.300000000 => ticks = 18, error = 0.000000000
request = 0.333333333 => ticks = 20, error = 0.000000000
request = 0.500000000 => ticks = 30, error = 0.000000000
request = 0.666666667 => ticks = 40, error = 0.000000000
request = 0.750000000 => ticks = 45, error = 0.000000000
request = 1.000000000 => ticks = 60, error = 0.000000000
request = 5.000000000 => ticks = 300, error = 0.000000000
request = 10.000000000 => ticks = 600, error = 0.000000000
request = 60.000000000 => ticks = 3600, error = 0.000000000
request = 100.000000000 => ticks = 6000, error = 0.000000000
New algorithm
request = 0.000000000 => ticks = 0, error = 0.000000000
request = 0.000000001 => ticks = 1, error = 0.016666666
request = 0.000001000 => ticks = 1, error = 0.016665667
request = 0.001000000 => ticks = 1, error = 0.015666667
request = 0.010000000 => ticks = 1, error = 0.006666667
request = 0.016666667 => ticks = 1, error = 0.000000000
request = 0.020000000 => ticks = 2, error = 0.013333333
request = 0.030000000 => ticks = 2, error = 0.003333333
request = 0.033333333 => ticks = 2, error = 0.000000000
request = 0.040000000 => ticks = 3, error = 0.010000000
request = 0.050000000 => ticks = 3, error = 0.000000000
request = 0.060000000 => ticks = 4, error = 0.006666667
request = 0.070000000 => ticks = 5, error = 0.013333333
request = 0.080000000 => ticks = 5, error = 0.003333333
request = 0.090000000 => ticks = 6, error = 0.010000000
request = 0.100000000 => ticks = 6, error = 0.000000000
request = 0.166666667 => ticks = 10, error = 0.000000000
request = 0.200000000 => ticks = 12, error = 0.000000000
request = 0.300000000 => ticks = 18, error = 0.000000000
request = 0.333333333 => ticks = 20, error = 0.000000000
request = 0.500000000 => ticks = 30, error = 0.000000000
request = 0.666666667 => ticks = 40, error = 0.000000000
request = 0.750000000 => ticks = 45, error = 0.000000000
request = 1.000000000 => ticks = 60, error = 0.000000000
request = 5.000000000 => ticks = 300, error = 0.000000000
request = 10.000000000 => ticks = 600, error = 0.000000000
request = 60.000000000 => ticks = 3600, error = 0.000000000
request = 100.000000000 => ticks = 6000, error = 0.000000000
Negative errors are bad. However this only represents the error in the
requested delay, not the actual range of delays that could occur depending on
the time remaining until the next clock tick. I have no idea whether the OSs
try to compensate for that...
BTW, on vxWorks the taskDelay() routine only returns an error in interrupt
context or if the task gets an unblocked signal. Our code has a problem in
the first case because we call errlogPrintf(), and in the latter case we never
check errno or try to restart the delay on an EINTR. Luckily nobody uses
signals much on vxWorks...
- Andrew
--
Never interrupt your enemy when he is making a mistake.
-- Napoleon Bonaparte
- Replies:
- Re: timer delay compensation Eric Norum
- References:
- timer delay compensation Hill, Jeff
- Navigate by Date:
- Prev:
Re: timer delay compensation Andrew Johnson
- Next:
Re: timer delay compensation Eric Norum
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
<2012>
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
RE: timer delay compensation Hill, Jeff
- Next:
Re: timer delay compensation Eric Norum
- Index:
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
<2012>
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|