On Fri, Feb 25, 2011 at 1:51 AM, Russ Cox <rsc@swtch.com> wrote:
> your layout in your first email (i think) assumes that wakeup
> can be called twice.

it doesn't.  the scenario in my first email has exactly one
sleep and one wakeup.

the canonical problem you have to avoid when implementing
sleep and wakeup is that the wakeup might happen before
the sleep has gotten around to sleeping.

There is a pattern in DragonFly BSD for use with tsleep (tsleep is evolutionarily related to p9's sleep, though the descent is tortuous), tsleep_interlock.

tsleep_interlock(WAITCHAN);
/* Kick off some operation or release some higher level lock or w/e */
tsleep(WAITCHAN, ...);

tsleep_interlock queues a process but does not actually go to sleep. If a wakeup happens after the tsleep_interlock but before tsleep has fully slept, the process does not sleep in tsleep().

I do not know if a similar design would be feasible given Plan 9's sleep/wakeup; at first glance, it looks to be so - sleep_interlock would look similar to sleep's front-end, but it would not 'gotolabel(&m->sched)'.

-- vs