diff options
Diffstat (limited to 'src/runtime/proc.go')
| -rw-r--r-- | src/runtime/proc.go | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/src/runtime/proc.go b/src/runtime/proc.go index 24a62492e1..099605fe52 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -1435,6 +1435,10 @@ func needm(x byte) { // Initialize this thread to use the m. asminit() minit() + + // mp.curg is now a real goroutine. + casgstatus(mp.curg, _Gdead, _Gsyscall) + atomic.Xadd(&sched.ngsys, -1) } var earlycgocallback = []byte("fatal error: cgo callback before cgo call\n") @@ -1477,9 +1481,11 @@ func oneNewExtraM() { gp.stktopsp = gp.sched.sp gp.gcscanvalid = true gp.gcscandone = true - // malg returns status as Gidle, change to Gsyscall before adding to allg - // where GC will see it. - casgstatus(gp, _Gidle, _Gsyscall) + // malg returns status as _Gidle. Change to _Gdead before + // adding to allg where GC can see it. We use _Gdead to hide + // this from tracebacks and stack scans since it isn't a + // "real" goroutine until needm grabs it. + casgstatus(gp, _Gidle, _Gdead) gp.m = mp mp.curg = gp mp.locked = _LockInternal @@ -1492,6 +1498,12 @@ func oneNewExtraM() { // put on allg for garbage collector allgadd(gp) + // gp is now on the allg list, but we don't want it to be + // counted by gcount. It would be more "proper" to increment + // sched.ngfree, but that requires locking. Incrementing ngsys + // has the same effect. + atomic.Xadd(&sched.ngsys, +1) + // Add m to the extra list. mnext := lockextra(true) mp.schedlink.set(mnext) @@ -1528,6 +1540,10 @@ func dropm() { // with no pointer manipulation. mp := getg().m + // Return mp.curg to dead state. + casgstatus(mp.curg, _Gsyscall, _Gdead) + atomic.Xadd(&sched.ngsys, +1) + // Block signals before unminit. // Unminit unregisters the signal handling stack (but needs g on some systems). // Setg(nil) clears g, which is the signal handler's cue not to run Go handlers. |
