]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix semasleep on Plan 9
authorDavid du Colombier <0intro@gmail.com>
Thu, 10 Apr 2014 04:36:20 +0000 (06:36 +0200)
committerDavid du Colombier <0intro@gmail.com>
Thu, 10 Apr 2014 04:36:20 +0000 (06:36 +0200)
If you pass ns = 100,000 to this function, timediv will
return ms = 0. tsemacquire in /sys/src/9/port/sysproc.c
will return immediately when ms == 0 and the semaphore
cannot be acquired immediately - it doesn't sleep - so
notetsleep will spin, chewing cpu and repeatedly reading
the time, until the 100us have passed.

Thanks to the time reads it won't take too many iterations,
but whatever we are waiting for does not get a chance to
run. Eventually the notetsleep spin loop returns and we
end up in the stoptheworld spin loop - actually a sleep
loop but we're not doing a good job of sleeping.

After 100ms or so of this, the kernel says enough and
schedules a different thread. That thread manages to do
whatever we're waiting for, and the spinning in the other
thread stops. If tsemacquire had actually slept, this
would have happened much quicker.

Many thanks to Russ Cox for help debugging.

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/86210043

src/pkg/runtime/os_plan9.c

index b634fd73db256c14ccfa086ab94cbe8d4e11232c..ec88738c3884a1cf2a8661252f177c0001c6f8fb 100644 (file)
@@ -283,6 +283,8 @@ runtime·semasleep(int64 ns)
 
        if(ns >= 0) {
                ms = runtime·timediv(ns, 1000000, nil);
+               if(ms == 0)
+                       ms = 1;
                ret = runtime·plan9_tsemacquire(&m->waitsemacount, ms);
                if(ret == 1)
                        return 0;  // success