Evan Hillas <evanh@clear.net.nz> wrote:
David Gibbs wrote:
True it isn’t a guarenteed method – but, really, nothing is. For
more precise work, you do need an external hardware timer, the better
quality the hw timer, the better your precision.
What I mean is it’s not clear that the stored resolution is the only
factor in the calculation for each clock tick. That we are not
guaranteed that using this resolution figure will produce a flawless
metronome. Ie, Absolutely no error accumulating resulting in no
skipping/dropping ticks for event generation.
Unless you miss hardware interrupts (due to extended periods of
interrupts being disabled, masked, or some hardware errors), as long
as you use a multiple of the timer frequency and use CLOCK_MONOTONIC,
there should be no further accumulated error – there should be no
other factor in the calculation for clock tick.
QNX Neutrino stores time internally as 2 64-bit nanosecond values:
a) nanoseconds since boot +
b) boot time in nanoseconds since Jan 1st 1970.
On each timer interrupt, once clock period (as reported by ClockPeriod())
is added to the nanoseconds since boot. If there is a current active
ClockAdjust(), then the adjust is added to the boot time as well.
Current time is a+b.
CLOCK_REALTIME timers fire based on a+b.
CLOCK_MONOTIC timers fire based on a.
Now, I’m not sure what you mean by “added jitter”, especially as mentioned
in the tick-tock articles.
The skipping/dropping is what I mean by intentional adding of jitter -
from the app’s point-of-view. The tick-tock article refers to this as
a beat but from the pov of an unwanted signal it’s also jitter.
I guess I could have also said noise.
Yes, but I said to use an exact multiple of the ClockPeriod(), so you won’t
get this noise/jitter/beat.
I recommended ClockPeriod(), rather than clock_getres(), though I expect
that clock_getres() actually just calls ClockPeriod(). From what I have
seen, ClockPeriod() gives the actual value the OS is using, the actual
calculated interval.
e.g. if I set the clock period to 1ms, and then do a ClockPeriod() to
query it, I will see 999847 ns as the result.
Yup, and any future enhancements have a chance to break any app that
relies on shuffling an exact multiple of the OS calculation. You are
right about using ClockPeriod() - any use of the extended data-structure
will show up there but not so likely in clock_getres().
You have to be a bit smart about figuring out your exact multiple. Query
the fundamental clock period, then calculate the closest match between
integer multiples of that value and what your actual wanted period is.
You may, even, need to as part of your system design choose a different
clock period to give closer/better/more accurate results.
But, yeah, if you naively hard-code it as 15* ClockPeriod(), that could
definitely cause problems.
-David
David Gibbs
QNX Training Services
dagibbs@qnx.com