aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/malloc.go
diff options
context:
space:
mode:
authorDavid du Colombier <0intro@gmail.com>2015-10-28 06:44:26 +0100
committerDavid du Colombier <0intro@gmail.com>2015-10-28 05:45:24 +0000
commit31430bda0988aed3dab6ee48c00afc1b0fb65093 (patch)
treec0ff1cf120bb88d2f0da6adaa7bf2fda2be016c9 /src/runtime/malloc.go
parent6736cb0df122fdcb0e23c9aba16ebf49ae47b12c (diff)
downloadgo-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.go21
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