]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: don't use FP when calling nextSample in the Plan 9 sighandler
authorDavid du Colombier <0intro@gmail.com>
Wed, 28 Oct 2015 05:44:26 +0000 (06:44 +0100)
committerDavid du Colombier <0intro@gmail.com>
Wed, 28 Oct 2015 05:45:24 +0000 (05:45 +0000)
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>
src/runtime/malloc.go

index b86d41faac3219a6bf6c3421cf4d8f970eb65a2b..23c15da4139d2f95e6fc1c6332700302ac17a9eb 100644 (file)
@@ -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