diff options
Diffstat (limited to 'libgo/runtime/thread-linux.c')
-rw-r--r-- | libgo/runtime/thread-linux.c | 24 |
1 files changed, 11 insertions, 13 deletions
diff --git a/libgo/runtime/thread-linux.c b/libgo/runtime/thread-linux.c index 13d23c47b07..ae56261e6f5 100644 --- a/libgo/runtime/thread-linux.c +++ b/libgo/runtime/thread-linux.c @@ -4,6 +4,7 @@ #include "runtime.h" #include "defs.h" +#include "signal_unix.h" // Linux futex. // @@ -33,25 +34,22 @@ typedef struct timespec Timespec; void runtime_futexsleep(uint32 *addr, uint32 val, int64 ns) { - Timespec ts, *tsp; - - if(ns < 0) - tsp = nil; - else { - ts.tv_sec = ns/1000000000LL; - ts.tv_nsec = ns%1000000000LL; - // Avoid overflow - if(ts.tv_sec > 1<<30) - ts.tv_sec = 1<<30; - tsp = &ts; - } + Timespec ts; + int32 nsec; // Some Linux kernels have a bug where futex of // FUTEX_WAIT returns an internal error code // as an errno. Libpthread ignores the return value // here, and so can we: as it says a few lines up, // spurious wakeups are allowed. - syscall(__NR_futex, addr, FUTEX_WAIT, val, tsp, nil, 0); + + if(ns < 0) { + syscall(__NR_futex, addr, FUTEX_WAIT, val, nil, nil, 0); + return; + } + ts.tv_sec = runtime_timediv(ns, 1000000000LL, &nsec); + ts.tv_nsec = nsec; + syscall(__NR_futex, addr, FUTEX_WAIT, val, &ts, nil, 0); } // If any procs are sleeping on addr, wake up at most cnt. |