Commit 09940b92 authored by Austin Clements's avatar Austin Clements Committed by Russ Cox

runtime: make p.gcBgMarkWorker a guintptr

Currently p.gcBgMarkWorker is a *g. Change it to a guintptr. This
eliminates a write barrier during the subtle mark worker parking dance
(which isn't known to be causing problems, but may).

Change-Id: Ibf12c05ac910820448059e69a68e5b882c993ed8
Reviewed-on: https://go-review.googlesource.com/18970
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: default avatarRick Hudson <rlh@golang.org>
Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent 08594ac7
...@@ -629,7 +629,7 @@ func (c *gcControllerState) findRunnableGCWorker(_p_ *p) *g { ...@@ -629,7 +629,7 @@ func (c *gcControllerState) findRunnableGCWorker(_p_ *p) *g {
if gcBlackenEnabled == 0 { if gcBlackenEnabled == 0 {
throw("gcControllerState.findRunnable: blackening not enabled") throw("gcControllerState.findRunnable: blackening not enabled")
} }
if _p_.gcBgMarkWorker == nil { if _p_.gcBgMarkWorker == 0 {
// The mark worker associated with this P is blocked // The mark worker associated with this P is blocked
// performing a mark transition. We can't run it // performing a mark transition. We can't run it
// because it may be on some other run or wait queue. // because it may be on some other run or wait queue.
...@@ -711,7 +711,7 @@ func (c *gcControllerState) findRunnableGCWorker(_p_ *p) *g { ...@@ -711,7 +711,7 @@ func (c *gcControllerState) findRunnableGCWorker(_p_ *p) *g {
} }
// Run the background mark worker // Run the background mark worker
gp := _p_.gcBgMarkWorker gp := _p_.gcBgMarkWorker.ptr()
casgstatus(gp, _Gwaiting, _Grunnable) casgstatus(gp, _Gwaiting, _Grunnable)
if trace.enabled { if trace.enabled {
traceGoUnpark(gp, 0) traceGoUnpark(gp, 0)
...@@ -1325,7 +1325,7 @@ func gcBgMarkStartWorkers() { ...@@ -1325,7 +1325,7 @@ func gcBgMarkStartWorkers() {
if p == nil || p.status == _Pdead { if p == nil || p.status == _Pdead {
break break
} }
if p.gcBgMarkWorker == nil { if p.gcBgMarkWorker == 0 {
go gcBgMarkWorker(p) go gcBgMarkWorker(p)
notetsleepg(&work.bgMarkReady, -1) notetsleepg(&work.bgMarkReady, -1)
noteclear(&work.bgMarkReady) noteclear(&work.bgMarkReady)
...@@ -1356,11 +1356,6 @@ func gcBgMarkWorker(_p_ *p) { ...@@ -1356,11 +1356,6 @@ func gcBgMarkWorker(_p_ *p) {
} }
var park parkInfo var park parkInfo
// casgp is casp for *g's.
casgp := func(gpp **g, old, new *g) bool {
return casp((*unsafe.Pointer)(unsafe.Pointer(gpp)), unsafe.Pointer(old), unsafe.Pointer(new))
}
gp := getg() gp := getg()
park.m = acquirem() park.m = acquirem()
park.attach = _p_ park.attach = _p_
...@@ -1397,7 +1392,7 @@ func gcBgMarkWorker(_p_ *p) { ...@@ -1397,7 +1392,7 @@ func gcBgMarkWorker(_p_ *p) {
// cas the worker because we may be // cas the worker because we may be
// racing with a new worker starting // racing with a new worker starting
// on this P. // on this P.
if !casgp(&p.gcBgMarkWorker, nil, g) { if !p.gcBgMarkWorker.cas(0, guintptr(unsafe.Pointer(g))) {
// The P got a new worker. // The P got a new worker.
// Exit this worker. // Exit this worker.
return false return false
...@@ -1409,7 +1404,7 @@ func gcBgMarkWorker(_p_ *p) { ...@@ -1409,7 +1404,7 @@ func gcBgMarkWorker(_p_ *p) {
// Loop until the P dies and disassociates this // Loop until the P dies and disassociates this
// worker (the P may later be reused, in which case // worker (the P may later be reused, in which case
// it will get a new worker) or we failed to associate. // it will get a new worker) or we failed to associate.
if _p_.gcBgMarkWorker != gp { if _p_.gcBgMarkWorker.ptr() != gp {
break break
} }
...@@ -1478,7 +1473,7 @@ func gcBgMarkWorker(_p_ *p) { ...@@ -1478,7 +1473,7 @@ func gcBgMarkWorker(_p_ *p) {
// as the worker for this P so // as the worker for this P so
// findRunnableGCWorker doesn't try to // findRunnableGCWorker doesn't try to
// schedule it. // schedule it.
_p_.gcBgMarkWorker = nil _p_.gcBgMarkWorker.set(nil)
releasem(park.m) releasem(park.m)
gcMarkDone() gcMarkDone()
......
...@@ -1867,9 +1867,9 @@ stop: ...@@ -1867,9 +1867,9 @@ stop:
// We have nothing to do. If we're in the GC mark phase, can // We have nothing to do. If we're in the GC mark phase, can
// safely scan and blacken objects, and have work to do, run // safely scan and blacken objects, and have work to do, run
// idle-time marking rather than give up the P. // idle-time marking rather than give up the P.
if _p_ := _g_.m.p.ptr(); gcBlackenEnabled != 0 && _p_.gcBgMarkWorker != nil && gcMarkWorkAvailable(_p_) { if _p_ := _g_.m.p.ptr(); gcBlackenEnabled != 0 && _p_.gcBgMarkWorker != 0 && gcMarkWorkAvailable(_p_) {
_p_.gcMarkWorkerMode = gcMarkWorkerIdleMode _p_.gcMarkWorkerMode = gcMarkWorkerIdleMode
gp := _p_.gcBgMarkWorker gp := _p_.gcBgMarkWorker.ptr()
casgstatus(gp, _Gwaiting, _Grunnable) casgstatus(gp, _Gwaiting, _Grunnable)
if trace.enabled { if trace.enabled {
traceGoUnpark(gp, 0) traceGoUnpark(gp, 0)
...@@ -3206,15 +3206,15 @@ func procresize(nprocs int32) *p { ...@@ -3206,15 +3206,15 @@ func procresize(nprocs int32) *p {
} }
// if there's a background worker, make it runnable and put // if there's a background worker, make it runnable and put
// it on the global queue so it can clean itself up // it on the global queue so it can clean itself up
if p.gcBgMarkWorker != nil { if gp := p.gcBgMarkWorker.ptr(); gp != nil {
casgstatus(p.gcBgMarkWorker, _Gwaiting, _Grunnable) casgstatus(gp, _Gwaiting, _Grunnable)
if trace.enabled { if trace.enabled {
traceGoUnpark(p.gcBgMarkWorker, 0) traceGoUnpark(gp, 0)
} }
globrunqput(p.gcBgMarkWorker) globrunqput(gp)
// This assignment doesn't race because the // This assignment doesn't race because the
// world is stopped. // world is stopped.
p.gcBgMarkWorker = nil p.gcBgMarkWorker.set(nil)
} }
for i := range p.sudogbuf { for i := range p.sudogbuf {
p.sudogbuf[i] = nil p.sudogbuf[i] = nil
......
...@@ -388,7 +388,7 @@ type p struct { ...@@ -388,7 +388,7 @@ type p struct {
// Per-P GC state // Per-P GC state
gcAssistTime int64 // Nanoseconds in assistAlloc gcAssistTime int64 // Nanoseconds in assistAlloc
gcBgMarkWorker *g gcBgMarkWorker guintptr
gcMarkWorkerMode gcMarkWorkerMode gcMarkWorkerMode gcMarkWorkerMode
// gcw is this P's GC work buffer cache. The work buffer is // gcw is this P's GC work buffer cache. The work buffer is
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment