Waiting until next system clock tick

I read the article titled ‘Tick-Tock’, which explains why usleep( 1000)
sleeps for 3ms rather than the expected 1ms. A number of usleep(1) calls in
succession (one after the other, so they end up syncing with the clock) will
sleep for 2ms each (twice the clock period). Is there a simple one-line
command that will wait until the next clock tick, regardless of how long
that delay actually ends up being? I’d love a little function such as
WaitClock():

for(;:wink: {
WaitClock();
// do stuff necessary once per millisecond
}

I realise this isn’t the most portable or clean code, but it sure would be
handy.

Thanks,
Shaun

Shaun Jackman <sjackman@nospam.vortek.com> wrote:

Is there a simple one-line command that will wait until the next
clock tick, regardless of how long that delay actually ends up being?

#include <sys/neutrino.h>
#include <sys/syspage.h>

attach_to_clock_tick() {
struct sigevent event;

// init ‘event’ variable here

// Note that you need to be running as ‘root’ for this to ThreadCtl()
// to succeed.
ThreadCtl(_NTO_TCTL_IO, NULL);

InterruptAttachEvent(SYSPAGE_ENTRY(qtime)->intr, &event, 0)

// Now the ‘event’ will be delivered once every clock tick.
}

Shaun Jackman <sjackman@nospam.vortek.com> wrote:

I read the article titled ‘Tick-Tock’, which explains why usleep( 1000)
sleeps for 3ms rather than the expected 1ms. A number of usleep(1) calls in
succession (one after the other, so they end up syncing with the clock) will
sleep for 2ms each (twice the clock period). Is there a simple one-line
command that will wait until the next clock tick, regardless of how long
that delay actually ends up being? I’d love a little function such as
WaitClock():

There isn’t one pre-written. It can be written a couple of ways, based
on whether or not you want you WaitClock() call to block, or run READY
while waiting for the clock to tick over.

– the blocking case uses a timer with the exact same expiry as the
ticksize.
– it uses a non-block MsgReceivePulse() to clear pending pulses
(to make sure you wait until the next tick, not return
immediately from a queued pulse)
– then a MsgReceivePulse() to wait for the next pulse
– can uses a private (locally created in per-thread data) channel
to make it thread-safe and make it not interfere with other channels
or get unblocked by other pulses

– the non-blocking (ready) case
– gets the system time
– loops, getting the system time until the system time changes

-David

for(;:wink: {
WaitClock();
// do stuff necessary once per millisecond
}

I realise this isn’t the most portable or clean code, but it sure would be
handy.

Thanks,
Shaun


QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

David Gibbs <dagibbs@qnx.com> wrote:

Shaun Jackman <> sjackman@nospam.vortek.com> > wrote:
I read the article titled ‘Tick-Tock’, which explains why usleep( 1000)
sleeps for 3ms rather than the expected 1ms. A number of usleep(1) calls in
succession (one after the other, so they end up syncing with the clock) will
sleep for 2ms each (twice the clock period). Is there a simple one-line
command that will wait until the next clock tick, regardless of how long
that delay actually ends up being? I’d love a little function such as
WaitClock():

There isn’t one pre-written. It can be written a couple of ways, based
on whether or not you want you WaitClock() call to block, or run READY
while waiting for the clock to tick over.

Ignore mine – Brian’s is better…using InterruptAttachEvent.
– you still might want to make sure you haven’t got extra events…

– it uses a non-block MsgReceivePulse() to clear pending pulses
(to make sure you wait until the next tick, not return
immediately from a queued pulse)
– then a MsgReceivePulse() to wait for the next pulse
– can uses a private (locally created in per-thread data) channel
to make it thread-safe and make it not interfere with other channels
or get unblocked by other pulses

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.