[inferno-npe] push by extrudedaluminiu - emu-DragonFly: Resolve osready() / osblock() race.... on 2010-10-28 20:07 GMT

2 views
Skip to first unread message

infer...@googlecode.com

unread,
Oct 28, 2010, 4:08:32 PM10/28/10
to inferno-n...@googlegroups.com
Revision: 6c8d13810d
Author: Venkatesh Srinivas <m...@endeavour.zapto.org>
Date: Thu Oct 28 13:07:36 2010
Log: emu-DragonFly: Resolve osready() / osblock() race.

Interlocks osready() and osblock(), so that an osready concurrent to or
before
an osblock would not result in a missed wakeup. Use DragonFly's umtx_sleep
and umtx_wakeup for kproc start/stop, rather than signal routines.

This race may still exist on other ports.

Reported-by: Francis Gudin
http://code.google.com/p/inferno-npe/source/detail?r=6c8d13810d

Modified:
/emu/DragonFly/os.c
/emu/port/proc.c

=======================================
--- /emu/DragonFly/os.c Fri Feb 12 09:46:25 2010
+++ /emu/DragonFly/os.c Thu Oct 28 13:07:36 2010
@@ -261,21 +261,38 @@
kill(p->sigid, SIGUSR1);
}

+// osblock and osready
+//
+// osblock blocks an Inferno kproc until it is woken by a corresponding
+// osready. We use the per-process os field (p->os) as a three-state
counter
+// to avoid lost osready() calls; block decrements this counter, while
+// ready increments it. On the 0 -> -1 transition in block, we use
+// DragonFly's umtx_sleep syscall to wait for the counter to be 0 again.
+// On a 1 -> 0 transition in block, we 'consume' a ready event and return.
+// In ready, on the 0 -> 1 transition, we return, while we use umtx_wakeup
+// on a -1 -> 0 transition.
+//
void
osblock(void)
{
- sigset_t mask;
-
- sigprocmask(SIG_SETMASK, NULL, &mask);
- sigdelset(&mask, SIGUSR2);
- sigsuspend(&mask);
+ int val;
+
+ val = _xadd(&up->os, -1);
+ if (val == 1)
+ return;
+
+ while((int) up->os == -1)
+ umtx_sleep(&up->os, -1, 1000 * 5);
}

void
osready(Proc *p)
{
- if(kill(p->sigid, SIGUSR2) < 0)
- fprint(2, "emu: osready failed: pid %d: %s\n", p->sigid,
strerror(errno));
+ int val;
+
+ val = _xadd(&p->os, 1);
+ if (val == -1)
+ umtx_wakeup(&p->os, 1);
}

void
=======================================
--- /emu/port/proc.c Tue Feb 9 09:34:34 2010
+++ /emu/port/proc.c Thu Oct 28 13:07:36 2010
@@ -22,6 +22,7 @@
addprog(p);

p->ksd = mallocz(sizeof(void*) * NKEYS, 1);
+ p->os = nil;

return p;
}

Reply all
Reply to author
Forward
0 new messages