diff options
| author | Dmitriy Vyukov <dvyukov@google.com> | 2013-07-29 22:22:34 +0400 |
|---|---|---|
| committer | Dmitriy Vyukov <dvyukov@google.com> | 2013-07-29 22:22:34 +0400 |
| commit | e84d9e1fb3a0d87abd60d31afb9cd0ddfb7d9bfa (patch) | |
| tree | 1a0213f1250994c0734456bdcd81bb1bf5e56ee4 /src/pkg/runtime/os_linux.c | |
| parent | b8734748b6b151a7fd724fc41e2555e6cd34385f (diff) | |
| download | go-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.c | 25 |
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. |
