wakeup() race condition. (theory)

pri=-10 Stuart Lynne sl at van-bc.UUCP
Sat Nov 26 10:07:08 AEST 1988


In article <455 at mrecvax.UUCP> tron at mrecvax.UUCP (Carlos Mendioroz) writes:
>Theory:
>Sleep & wakeup both call spl6() to ensure secure access to
>the process queues, (Well, this is not theory, the calls are
>there...) and it is possible for the driver's device to 
>interrupt as a wakeup() is running, isn't it ?
>
>As this driver (as SCO xenix serial driver) is running with
>prio 7, it's not blocked by spl6() and then it may interfere
>with the running wakeup by, say, runnig another wakeup.
>
>Solution: (?)
>Not to call any wakeup at prio 7, that is, put every driver
>interrupt routine that calls wakeup at prio 6 or below.
>
>I would be glad to hear some guru opinion on the topic.

This problem does exist when writing drivers under SCO Xenix. Specifically
things like:

	somewhere in driver, task side, eg read

		x = spl(5);
		state |= IAmAsleep;
		sleep(...)
		splx(x);

	somewhere in interrupt routine, ie received interrupt

		if (state&IAmAsleep) {
			state &= ~IAmAsleep;
			wakeup(...)
		}

The problem arises when the interrupt has a priority higher than the
protection level. There is a small window between when the task routine sets
the flag and actually performs the sleep call and is placed on the queue. If
the interrupt occurs there it see's the flag set and calls wakeup *before*
the process actually goes to sleep and because the flag gets reset nobody
ever try's to wake him up again.

SCO's line discipline routines protect things at spl5. While serial interrupts 
are handled at spl7 and the clock (and all poll routines) run at spl6.

The fix for this is to periodically (from a poll routine for example)
perform the wakeup call. This typically works because the task side are
typcially coded like:

		while ( CheckForCondition()) {
			state &=...
			wakeup(...)
		)

So periodically waking them up does no harm, just is slightly inefficent.

Don't know if this is the problem that you are encountering, and if it is it
would be hard to fix without access to source. It would be possible to add a
special driver which just had a poll routine which did a wakeup() on the 
appropriate variable address if you can figure out what it is.

-- 
Stuart.Lynne at wimsey.bc.ca {ubc-cs,uunet}!van-bc!sl     Vancouver,BC,604-937-7532



More information about the Comp.unix.wizards mailing list