]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: mark mstart as nowritebarrierrec
authorAustin Clements <austin@google.com>
Thu, 15 Jun 2017 19:02:32 +0000 (15:02 -0400)
committerAustin Clements <austin@google.com>
Wed, 11 Oct 2017 17:47:13 +0000 (17:47 +0000)
mstart is the entry point for new threads, so it certainly can't
interact with GC enough to have write barriers. We move the one small
piece that is allowed to have write barriers out into its own
function.

Change-Id: Id9c31d6ffac31d0051fab7db15eb428c11cadbad
Reviewed-on: https://go-review.googlesource.com/46035
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Rick Hudson <rlh@golang.org>
src/runtime/proc.go

index 6b96e97887e6caec0763bc20dbb850b28278e615..0fa0cf965e6d21552a9aed3912f2aaf9fea1291f 100644 (file)
@@ -1137,7 +1137,15 @@ func startTheWorldWithSema(emitTraceEvent bool) int64 {
 }
 
 // Called to start an M.
+//
+// This must not split the stack because we may not even have stack
+// bounds set up yet.
+//
+// May run during STW (because it doesn't have a P yet), so write
+// barriers are not allowed.
+//
 //go:nosplit
+//go:nowritebarrierrec
 func mstart() {
        _g_ := getg()
 
@@ -1176,12 +1184,7 @@ func mstart1() {
        // Install signal handlers; after minit so that minit can
        // prepare the thread to be able to handle the signals.
        if _g_.m == &m0 {
-               // Create an extra M for callbacks on threads not created by Go.
-               if iscgo && !cgoHasExtraM {
-                       cgoHasExtraM = true
-                       newextram()
-               }
-               initsig(false)
+               mstartm0()
        }
 
        if fn := _g_.m.mstartfn; fn != nil {
@@ -1198,6 +1201,21 @@ func mstart1() {
        schedule()
 }
 
+// mstartm0 implements part of mstart1 that only runs on the m0.
+//
+// Write barriers are allowed here because we know the GC can't be
+// running yet, so they'll be no-ops.
+//
+//go:yeswritebarrierrec
+func mstartm0() {
+       // Create an extra M for callbacks on threads not created by Go.
+       if iscgo && !cgoHasExtraM {
+               cgoHasExtraM = true
+               newextram()
+       }
+       initsig(false)
+}
+
 // forEachP calls fn(p) for every P p when p reaches a GC safe point.
 // If a P is currently executing code, this will bring the P to a GC
 // safe point and execute fn on that P. If the P is not executing code