aboutsummaryrefslogtreecommitdiff
path: root/src/runtime
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2017-06-15 15:02:32 -0400
committerAustin Clements <austin@google.com>2017-10-11 17:47:13 +0000
commita212083eea9ee745a3c8e7befb7bba4f4c95396c (patch)
treee5f4e88a9c9f735222a8c893b4244de831b2af12 /src/runtime
parent8f7f46f5a6d9fe821494aca3c689ca2572a42b41 (diff)
downloadgo-a212083eea9ee745a3c8e7befb7bba4f4c95396c.tar.xz
runtime: mark mstart as nowritebarrierrec
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>
Diffstat (limited to 'src/runtime')
-rw-r--r--src/runtime/proc.go30
1 files changed, 24 insertions, 6 deletions
diff --git a/src/runtime/proc.go b/src/runtime/proc.go
index 6b96e97887..0fa0cf965e 100644
--- a/src/runtime/proc.go
+++ b/src/runtime/proc.go
@@ -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