diff options
| author | Dmitriy Vyukov <dvyukov@google.com> | 2013-08-13 13:01:30 +0400 |
|---|---|---|
| committer | Dmitriy Vyukov <dvyukov@google.com> | 2013-08-13 13:01:30 +0400 |
| commit | e33e476e074c3f424ca5b9d14cf67acacd5250aa (patch) | |
| tree | 17dc781f20f0f494e3429b5790a2077abbc36e1a /src/pkg/runtime/proc.c | |
| parent | 9707f269c1eb7ee68a2be93e87eb49d481fb1a84 (diff) | |
| download | go-e33e476e074c3f424ca5b9d14cf67acacd5250aa.tar.xz | |
syscall: disable cpu profiling around fork
Fixes #5517.
Fixes #5659.
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/12183044
Diffstat (limited to 'src/pkg/runtime/proc.c')
| -rw-r--r-- | src/pkg/runtime/proc.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c index 994542c257..5574f0d6dc 100644 --- a/src/pkg/runtime/proc.c +++ b/src/pkg/runtime/proc.c @@ -1610,6 +1610,29 @@ exitsyscall0(G *gp) schedule(); // Never returns. } +// Called from syscall package before fork. +void +syscall·runtime_BeforeFork(void) +{ + // Fork can hang if preempted with signals frequently enough (see issue 5517). + // Ensure that we stay on the same M where we disable profiling. + m->locks++; + if(m->profilehz != 0) + runtime·resetcpuprofiler(0); +} + +// Called from syscall package after fork in parent. +void +syscall·runtime_AfterFork(void) +{ + int32 hz; + + hz = runtime·sched.profilehz; + if(hz != 0) + runtime·resetcpuprofiler(hz); + m->locks--; +} + // Hook used by runtime·malg to call runtime·stackalloc on the // scheduler stack. This exists because runtime·stackalloc insists // on being called on the scheduler stack, to avoid trying to grow @@ -2002,7 +2025,11 @@ runtime·setcpuprofilerate(void (*fn)(uintptr*, int32), int32 hz) if(fn == nil) hz = 0; - // Stop profiler on this cpu so that it is safe to lock prof. + // Disable preemption, otherwise we can be rescheduled to another thread + // that has profiling enabled. + m->locks++; + + // Stop profiler on this thread so that it is safe to lock prof. // if a profiling signal came in while we had prof locked, // it would deadlock. runtime·resetcpuprofiler(0); @@ -2017,6 +2044,8 @@ runtime·setcpuprofilerate(void (*fn)(uintptr*, int32), int32 hz) if(hz != 0) runtime·resetcpuprofiler(hz); + + m->locks--; } // Change number of processors. The world is stopped, sched is locked. |
