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.

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

specify both blocking states for the flags argument to TimerTimeout(), because the<br />

client might get blocked in either state.<br />

To specify multiple states, you simply OR them together:<br />

TimerTimeout (... _NTO_TIMEOUT_SEND | _NTO_TIMEOUT_REPLY, ...);<br />

This causes the timeout to be active whenever the kernel enters either the<br />

SEND-blocked state or the REPLY-blocked state. There’s nothing special about<br />

entering the SEND-blocked state and timing out — the server hasn’t received the<br />

message yet, so the server isn’t actively doing anything on behalf of the client. This<br />

means that if the kernel times out a SEND-blocked client, the server doesn’t have to be<br />

informed. The client’s MsgSend() function returns an ETIMEDOUT indication, and<br />

processing has completed for the timeout.<br />

However, as was mentioned in the Message Passing chapter (under<br />

“_NTO_CHF_UNBLOCK”), if the server has already received the client’s message, and<br />

the client wishes to unblock, there are two choices for the server. If the server has not<br />

specified _NTO_CHF_UNBLOCK on the channel it received the message on, then the<br />

client will be unblocked immediately, and the server won’t receive any indication that<br />

an unblock has occurred. Most of the servers I’ve seen always have the<br />

_NTO_CHF_UNBLOCK flag enabled. In that case, the kernel delivers a pulse to the<br />

server, but the client remains blocked until the server replies! As mentioned in the<br />

above-referenced section of the Message Passing chapter, this is done so that the server<br />

has an indication that it should do something about the client’s unblock request.<br />

Summary<br />

We’ve looked at <strong>Neutrino</strong>’s time-based functions, including timers and how they can<br />

be used, as well as kernel timeouts. Relative timers provide some form of event “in a<br />

certain number of seconds,” while absolute timers provide this event “at a certain<br />

time.” Timers (and, generally speaking, the struct sigevent) can cause the<br />

delivery of a pulse, a signal, or a thread to start.<br />

The kernel implements timers by storing the absolute time that represents the next<br />

“event” on a sorted queue, and comparing the current time (as derived by the timer tick<br />

interrupt service routine) against the head of the sorted queue. When the current time<br />

is greater than or equal to the first member of the queue, the queue is processed (for all<br />

matching entries) and the kernel dispatches events or threads (depending on the type<br />

of queue entry) and (possibly) reschedules.<br />

To provide support for power-saving features, you should disable periodic timers when<br />

they’re not needed — otherwise, the power-saving feature won’t implement power<br />

saving, because it believes that there’s something to “do” periodically.<br />

You could also use the CLOCK_SOFTTIME clock source, unless of course you<br />

actually wanted the timer to defeat the power saving feature.<br />

Given the different types of clock sources, you have flexibility in determining the basis<br />

of your clocks and timer; from “real, elapsed” time through to time sources that are<br />

based on power management activities.<br />

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

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

Saved successfully!

Ooh no, something went wrong!