runtime: switch p.gcFractionalMarkTime to atomic.Int64

atomic.Int64 automatically maintains proper alignment, avoiding the need
to manually adjust alignment back and forth as fields above change.

Change-Id: I6a6a636c4c3c366353f6dc8ecac473c075dd5cd9
Reviewed-on: https://go-review.googlesource.com/c/go/+/716700
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
This commit is contained in:
Michael Pratt 2025-10-30 16:33:30 -04:00 committed by Gopher Robot
parent 8873e8bea2
commit d3aeba1670
4 changed files with 5 additions and 6 deletions

View file

@ -14,7 +14,6 @@ import "unsafe"
// operations (all the *64 operations in internal/runtime/atomic). // operations (all the *64 operations in internal/runtime/atomic).
var AtomicFields = []uintptr{ var AtomicFields = []uintptr{
unsafe.Offsetof(m{}.procid), unsafe.Offsetof(m{}.procid),
unsafe.Offsetof(p{}.gcFractionalMarkTime),
unsafe.Offsetof(profBuf{}.overflow), unsafe.Offsetof(profBuf{}.overflow),
unsafe.Offsetof(profBuf{}.overflowTime), unsafe.Offsetof(profBuf{}.overflowTime),
unsafe.Offsetof(heapStatsDelta{}.tinyAllocCount), unsafe.Offsetof(heapStatsDelta{}.tinyAllocCount),

View file

@ -316,7 +316,7 @@ func pollFractionalWorkerExit() bool {
return true return true
} }
p := getg().m.p.ptr() p := getg().m.p.ptr()
selfTime := p.gcFractionalMarkTime + (now - p.gcMarkWorkerStartTime) selfTime := p.gcFractionalMarkTime.Load() + (now - p.gcMarkWorkerStartTime)
// Add some slack to the utilization goal so that the // Add some slack to the utilization goal so that the
// fractional worker isn't behind again the instant it exits. // fractional worker isn't behind again the instant it exits.
return float64(selfTime)/float64(delta) > 1.2*gcController.fractionalUtilizationGoal return float64(selfTime)/float64(delta) > 1.2*gcController.fractionalUtilizationGoal
@ -1858,7 +1858,7 @@ func gcBgMarkWorker(ready chan struct{}) {
pp.limiterEvent.stop(limiterEventIdleMarkWork, now) pp.limiterEvent.stop(limiterEventIdleMarkWork, now)
} }
if pp.gcMarkWorkerMode == gcMarkWorkerFractionalMode { if pp.gcMarkWorkerMode == gcMarkWorkerFractionalMode {
atomic.Xaddint64(&pp.gcFractionalMarkTime, duration) pp.gcFractionalMarkTime.Add(duration)
} }
// We'll releasem after this point and thus this P may run // We'll releasem after this point and thus this P may run

View file

@ -427,7 +427,7 @@ func (c *gcControllerState) startCycle(markStartTime int64, procs int, trigger g
// Clear per-P state // Clear per-P state
for _, p := range allp { for _, p := range allp {
p.gcAssistTime = 0 p.gcAssistTime = 0
p.gcFractionalMarkTime = 0 p.gcFractionalMarkTime.Store(0)
} }
if trigger.kind == gcTriggerTime { if trigger.kind == gcTriggerTime {
@ -830,7 +830,7 @@ func (c *gcControllerState) findRunnableGCWorker(pp *p, now int64) (*g, int64) {
// //
// This should be kept in sync with pollFractionalWorkerExit. // This should be kept in sync with pollFractionalWorkerExit.
delta := now - c.markStartTime delta := now - c.markStartTime
if delta > 0 && float64(pp.gcFractionalMarkTime)/float64(delta) > c.fractionalUtilizationGoal { if delta > 0 && float64(pp.gcFractionalMarkTime.Load())/float64(delta) > c.fractionalUtilizationGoal {
// Nope. No need to run a fractional worker. // Nope. No need to run a fractional worker.
gcBgMarkWorkerPool.push(&node.node) gcBgMarkWorkerPool.push(&node.node)
return nil, now return nil, now

View file

@ -794,7 +794,7 @@ type p struct {
// Per-P GC state // Per-P GC state
gcAssistTime int64 // Nanoseconds in assistAlloc gcAssistTime int64 // Nanoseconds in assistAlloc
gcFractionalMarkTime int64 // Nanoseconds in fractional mark worker (atomic) gcFractionalMarkTime atomic.Int64 // Nanoseconds in fractional mark worker
// limiterEvent tracks events for the GC CPU limiter. // limiterEvent tracks events for the GC CPU limiter.
limiterEvent limiterEvent limiterEvent limiterEvent