26.02.2014 Views

Getting Started with QNX Neutrino - QNX Software Systems

Getting Started with QNX Neutrino - QNX Software Systems

Getting Started with QNX Neutrino - QNX Software Systems

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Clocks and timers<br />

© 2009, <strong>QNX</strong> <strong>Software</strong> <strong>Systems</strong> GmbH & Co. KG.<br />

In those days, since nothing else was running on the machine, this didn’t present much<br />

of a problem, because no other process cared that you were hogging 100% of the CPU<br />

in the sleep() function.<br />

Even today, we sometimes hog 100% of the CPU to do timing functions. Notably, the<br />

nanospin() function is used to obtain very fine-grained timing, but it does so at the<br />

expense of burning CPU at its priority. Use <strong>with</strong> caution!<br />

If you did have to perform some form of “multitasking,” it was usually done via an<br />

interrupt routine that would hang off the hardware timer or be performed <strong>with</strong>in the<br />

“busy-wait” period, somewhat affecting the calibration of the timing. This usually<br />

wasn’t a concern.<br />

Luckily we’ve progressed far beyond that point. Recall from “Scheduling and the real<br />

world,” in the Processes and Threads chapter, what causes the kernel to reschedule<br />

threads:<br />

• a hardware interrupt<br />

• a kernel call<br />

• a fault (exception)<br />

In this chapter, we’re concerned <strong>with</strong> the first two items on the list: the hardware<br />

interrupt and the kernel call.<br />

When a thread calls sleep(), the C library contains code that eventually makes a kernel<br />

call. This call tells the kernel, “Put this thread on hold for a fixed amount of time.” The<br />

call removes the thread from the running queue and starts a timer.<br />

Meanwhile, the kernel has been receiving regular hardware interrupts from the<br />

computer’s clock hardware. Let’s say, for argument’s sake, that these hardware<br />

interrupts occur at exactly 10-millisecond intervals.<br />

Let’s restate: every time one of these interrupts is handled by the kernel’s clock<br />

interrupt service routine (ISR), it means that 10 ms have gone by. The kernel keeps<br />

track of the time of day by incrementing its time-of-day variable by an amount<br />

corresponding to 10 ms every time the ISR runs.<br />

So when the kernel implements a 15-second timer, all it’s really doing is:<br />

1 Setting a variable to the current time plus 15 seconds.<br />

2 In the clock ISR, comparing this variable against the time of day.<br />

3 When the time of day is the same as (or greater than) the variable, putting the<br />

thread back onto the READY queue.<br />

When multiple timers are outstanding, as would be the case if several threads all<br />

needed to be woken at different times, the kernel would simply queue the requests,<br />

sorting them by time order — the nearest one would be at the head of the queue, and<br />

so on. The variable that the ISR looks at is the one at the head of this queue.<br />

138 Chapter 3 • Clocks, Timers, and <strong>Getting</strong> a Kick Every So Often April 30, 2009

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!