Subject: Re: Bare tsleep in dev/ic/wdc.c
To: Manuel Bouyer <bouyer@antioche.lip6.fr>
From: Bill Sommerfeld <sommerfeld@orchard.arlington.ma.us>
List: tech-kern
Date: 07/25/1999 07:02:20
> How can a spurious wakeup happen ? The only place where wakeup() is called
> on wdc_c is in __wdccommand_done(), and AT_DONE is set before ...

Well, besides the possibility that you could randomly get hit with a
setrunnable() call, there's also the chance that (if you're sleeping
on the address of a dynamically allocated data structure) there may be
a spurious wakeup due to (for instance) a stray timer callout which
just does a wakeup() because some other part of the system failed to
do an untimeout() before a free.

Anyhow, the Ancient and Honorable Lore which was passed down to me
when I was first learning to write kernel code was that you always
"guard" sleep() with a loop testing whether the condition was
satisfied, because:

 1) There might be multiple processes waiting for the condition to
happen (and another one might wake up first and grab the resource you
were waiting for).
	
 2) You might get woken up prematurely.

I think it's mostly a matter of good style/defensive coding...  The
loop doesn't cost very much in most cases, and it makes it more likely
that a spurious wakeup won't do any damage.

(It also occurs to me that as we move to SMP, spurious wakeups are
going to be a bit more difficult to avoid without significantly
complicating locking protocols).

						- Bill