aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/os_linux.c
diff options
context:
space:
mode:
authorDmitriy Vyukov <dvyukov@google.com>2013-07-29 22:22:34 +0400
committerDmitriy Vyukov <dvyukov@google.com>2013-07-29 22:22:34 +0400
commite84d9e1fb3a0d87abd60d31afb9cd0ddfb7d9bfa (patch)
tree1a0213f1250994c0734456bdcd81bb1bf5e56ee4 /src/pkg/runtime/os_linux.c
parentb8734748b6b151a7fd724fc41e2555e6cd34385f (diff)
downloadgo-e84d9e1fb3a0d87abd60d31afb9cd0ddfb7d9bfa.tar.xz
runtime: do not split stacks in syscall status
Split stack checks (morestack) corrupt g->sched, but g->sched must be preserved consistent for GC/traceback. The change implements runtime.notetsleepg function, which does entersyscall/exitsyscall and is carefully arranged to not call any split functions in between. R=rsc CC=golang-dev https://golang.org/cl/11575044
Diffstat (limited to 'src/pkg/runtime/os_linux.c')
-rw-r--r--src/pkg/runtime/os_linux.c25
1 files changed, 10 insertions, 15 deletions
diff --git a/src/pkg/runtime/os_linux.c b/src/pkg/runtime/os_linux.c
index b27239d46f..038208b60c 100644
--- a/src/pkg/runtime/os_linux.c
+++ b/src/pkg/runtime/os_linux.c
@@ -32,30 +32,25 @@ enum
// if(*addr == val) sleep
// Might be woken up spuriously; that's allowed.
// Don't sleep longer than ns; ns < 0 means forever.
+#pragma textflag 7
void
runtime·futexsleep(uint32 *addr, uint32 val, int64 ns)
{
- Timespec ts, *tsp;
- int64 secs;
-
- if(ns < 0)
- tsp = nil;
- else {
- secs = ns/1000000000LL;
- // Avoid overflow
- if(secs > 1LL<<30)
- secs = 1LL<<30;
- ts.tv_sec = secs;
- ts.tv_nsec = ns%1000000000LL;
- tsp = &ts;
- }
+ Timespec ts;
// 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.
- runtime·futex(addr, FUTEX_WAIT, val, tsp, nil, 0);
+
+ if(ns < 0) {
+ runtime·futex(addr, FUTEX_WAIT, val, nil, nil, 0);
+ return;
+ }
+ ts.tv_nsec = 0;
+ ts.tv_sec = runtime·timediv(ns, 1000000000LL, (int32*)&ts.tv_nsec);
+ runtime·futex(addr, FUTEX_WAIT, val, &ts, nil, 0);
}
// If any procs are sleeping on addr, wake up at most cnt.