In article <9hakmh$an6$3@nntp.qnx.com>, David Gibbs <dagibbs@qnx.com>
wrote:
Eric Berdahl <> berdahl@intelligentparadigm.com> > wrote:
In article <9gvq2r$1r7$> 1@inn.qnx.com> >,
“Mario Charest” <> mcharest@deletezinformatic.com> > wrote:
The downside of spinning is that I’m consuming the CPU with no real work
being done. I am therefore degrading system performance. When I’m a low
priority driver spinning for several hundred nanoseconds, this is
generally not a problem. Eventually, the scheduler will kick in and
allow another runnable thread to take time.
Of course, if the a higher priority thread does pre-empt you, then
your count for the nanospin will stop counting, and you’ll wait for
longer than you wanted.
In fact, something like nanospin() is only accurate if it is the
highest priority thing around.
Correct. Which is one reason I don’t advocate using nanospin for
“accurate” timing. IMHO, nanospin is really only useful for client
accessing hardware at a very very low level.
For example, one of my PCI cards has a serial EEPROM chip where startup
data is stored. The chip is read by the card at startup time to
initialize itself. My driver can write to the chip at other times to
change the settings which should be used at the next startup.
Unfortunately, the software interface to the chip involves writing a
register which maps directly to the serial bus feeding the EEPROM. So, I
have to toggle the select, data, clock, and R/W lines directly. It’s a
bit of a pain, but not unreasonable. The big catch is that I have to
obey the timing requirements of the bus (e.g. setup and hold
restrictions).
If I use timers, delays, sleeps, or anything involving the scheduler,
the shortest interval I can practically get is on the order of
milliseconds (1-5), but the timing requirements of the bus are on the
order of microseconds (10).
Thus, if I use usleep, sleep, delay, or the like, my transfer speed is
degraded by a couple orders of magnitude. Yuck.
If I use nanosleep and I’m pre-empted, I wait a while for that one spin
and continue, which is just fine. Overall, my transfer speed is
reasonable given the priority of the thread which is doing the transfer.
If I use nanosleep and I’m not pre-empted, my transfer speed is as good
as I can get it and overall system performance is not negatively
affected (unless I run this in a high-priority thread, which would be a
silly thing for me to do and would be my own damn fault if I did).
This gets back to the whole “Why would I spin when I could block?” and
“Why would I block when I could spin?” questions. The ultimate answer
involves understanding your tools and your system design, and then
deciding which is the best tool for the job.