diff options
| author | David du Colombier <0intro@gmail.com> | 2015-10-28 06:44:26 +0100 |
|---|---|---|
| committer | David du Colombier <0intro@gmail.com> | 2015-10-28 05:45:24 +0000 |
| commit | 31430bda0988aed3dab6ee48c00afc1b0fb65093 (patch) | |
| tree | c0ff1cf120bb88d2f0da6adaa7bf2fda2be016c9 /src/runtime/malloc.go | |
| parent | 6736cb0df122fdcb0e23c9aba16ebf49ae47b12c (diff) | |
| download | go-31430bda0988aed3dab6ee48c00afc1b0fb65093.tar.xz | |
runtime: don't use FP when calling nextSample in the Plan 9 sighandler
In the Go signal handler on Plan 9, when a signal with
the _SigThrow flag is received, we call startpanic before
printing the stack trace.
The startpanic function calls systemstack which calls
startpanic_m. In the startpanic_m function, we call
allocmcache to allocate _g_.m.mcache. The problem is
that allocmcache calls nextSample, which does a floating
point operation to return a sampling point for heap profiling.
However, Plan 9 doesn't support floating point in the
signal handler.
This change adds a new function nextSampleNoFP, only
called when in the Plan 9 signal handler, which is
similar to nextSample, but avoids floating point.
Change-Id: Iaa30437aa0f7c8c84d40afbab7567ad3bd5ea2de
Reviewed-on: https://go-review.googlesource.com/16307
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime/malloc.go')
| -rw-r--r-- | src/runtime/malloc.go | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go index b86d41faac..23c15da413 100644 --- a/src/runtime/malloc.go +++ b/src/runtime/malloc.go @@ -826,6 +826,13 @@ func profilealloc(mp *m, x unsafe.Pointer, size uintptr) { // distributed random number and applying the cumulative distribution // function for an exponential. func nextSample() int32 { + if GOOS == "plan9" { + // Plan 9 doesn't support floating point in note handler. + if g := getg(); g == g.m.gsignal { + return nextSampleNoFP() + } + } + period := MemProfileRate // make nextSample not overflow. Maximum possible step is @@ -855,6 +862,20 @@ func nextSample() int32 { return int32(qlog*(minusLog2*float64(period))) + 1 } +// nextSampleNoFP is similar to nextSample, but uses older, +// simpler code to avoid floating point. +func nextSampleNoFP() int32 { + // Set first allocation sample size. + rate := MemProfileRate + if rate > 0x3fffffff { // make 2*rate not overflow + rate = 0x3fffffff + } + if rate != 0 { + return int32(int(fastrand1()) % (2 * rate)) + } + return 0 +} + type persistentAlloc struct { base unsafe.Pointer off uintptr |
