From: David du Colombier <0intro@gmail.com> Date: Wed, 28 Oct 2015 05:44:26 +0000 (+0100) Subject: runtime: don't use FP when calling nextSample in the Plan 9 sighandler X-Git-Tag: go1.6beta1~701 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=31430bda0988aed3dab6ee48c00afc1b0fb65093;p=gostls13.git 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 Reviewed-by: Ian Lance Taylor --- 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