Subject: interrupts, threads, and preventing wakeup-before-sleep?
To: None <>
From: None <>
List: tech-kern
Date: 02/17/2003 21:51:52
Uh, how am I supposed to prevent a wakeup-before-sleep condition when the
waker is an interrupt? I've got an interrupt I want to coordinate with a
thread by way of a sleep/wakeup pair of calls.

Now, when the thread enters a critical section it needs to be sure state
isn't going to change out from underneath it before it can get to sleep.
The ltsleep() call seems right for this. BUT:

              dler.  For a simplelock to be used in an interrupt handler, care
              must be taken to disable the interrupt, acquire the lock, do any
              processing, release the simplelock and re-enable the interrupt.
              This procedure is necessary to avoid deadlock between the inter-
              rupt handler and other threads executing on the same processor.

Now, ltsleep() is not documented as doing anything to the interrupt mask.
So if the proper spl call is made before locking a simple lock and the
lock is used with ltsleep() then the spl level will not be lowered! This
makes simple locks useless when trying to prevent a wakeup-before-sleep
condition where the waker is an interrupt, and therefore makes ltsleep()
useless in this case.

Even better, sys/lock.h has this little gem in the non-SMP non-LOCKDEBUG

#ifndef lint            
#define simple_lock(alp)        (void)(alp)
#define simple_unlock(alp)      (void)(alp)
#else /* lint */
#define simple_lock(alp)        /* nothing */ 
#define simple_unlock(alp)      /* nothing */

So, simple locks don't actually do anything at all, are useless for
coordination between multiple threads, and are useless in the
aforementioned wakeup-sleep issue. It would be handy if the docs were
this clear. 

Kevin P. Neal                      

"Nonbelievers found it difficult to defend their position in \ 
    the presense of a working computer." -- a DEC Jensen paper