summaryrefslogtreecommitdiff
path: root/libgo/runtime/thread-linux.c
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/runtime/thread-linux.c')
-rw-r--r--libgo/runtime/thread-linux.c24
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.