@@ -92,8 +92,6 @@ type gcControllerState struct {
92
92
// Initialized from GOGC. GOGC=off means no GC.
93
93
gcPercent atomic.Int32
94
94
95
- _ uint32 // padding so following 64-bit values are 8-byte aligned
96
-
97
95
// memoryLimit is the soft memory limit in bytes.
98
96
//
99
97
// Initialized from GOMEMLIMIT. GOMEMLIMIT=off is equivalent to MaxInt64
@@ -145,8 +143,6 @@ type gcControllerState struct {
145
143
// consMark; see consMark for details.
146
144
consMarkController piController
147
145
148
- _ uint32 // Padding for atomics on 32-bit platforms.
149
-
150
146
// gcPercentHeapGoal is the goal heapLive for when next GC ends derived
151
147
// from gcPercent.
152
148
//
@@ -289,11 +285,10 @@ type gcControllerState struct {
289
285
// that assists and background mark workers started.
290
286
markStartTime int64
291
287
292
- // dedicatedMarkWorkersNeeded is the number of dedicated mark
293
- // workers that need to be started. This is computed at the
294
- // beginning of each cycle and decremented atomically as
295
- // dedicated mark workers get started.
296
- dedicatedMarkWorkersNeeded int64
288
+ // dedicatedMarkWorkersNeeded is the number of dedicated mark workers
289
+ // that need to be started. This is computed at the beginning of each
290
+ // cycle and decremented as dedicated mark workers get started.
291
+ dedicatedMarkWorkersNeeded atomic.Int64
297
292
298
293
// idleMarkWorkers is two packed int32 values in a single uint64.
299
294
// These two values are always updated simultaneously.
@@ -448,26 +443,26 @@ func (c *gcControllerState) startCycle(markStartTime int64, procs int, trigger g
448
443
// 25%. For small GOMAXPROCS, this would introduce too much
449
444
// error, so we add fractional workers in that case.
450
445
totalUtilizationGoal := float64 (procs ) * gcBackgroundUtilization
451
- c . dedicatedMarkWorkersNeeded = int64 (totalUtilizationGoal + 0.5 )
452
- utilError := float64 (c . dedicatedMarkWorkersNeeded )/ totalUtilizationGoal - 1
446
+ dedicatedMarkWorkersNeeded : = int64 (totalUtilizationGoal + 0.5 )
447
+ utilError := float64 (dedicatedMarkWorkersNeeded )/ totalUtilizationGoal - 1
453
448
const maxUtilError = 0.3
454
449
if utilError < - maxUtilError || utilError > maxUtilError {
455
450
// Rounding put us more than 30% off our goal. With
456
451
// gcBackgroundUtilization of 25%, this happens for
457
452
// GOMAXPROCS<=3 or GOMAXPROCS=6. Enable fractional
458
453
// workers to compensate.
459
- if float64 (c . dedicatedMarkWorkersNeeded ) > totalUtilizationGoal {
454
+ if float64 (dedicatedMarkWorkersNeeded ) > totalUtilizationGoal {
460
455
// Too many dedicated workers.
461
- c . dedicatedMarkWorkersNeeded --
456
+ dedicatedMarkWorkersNeeded --
462
457
}
463
- c .fractionalUtilizationGoal = (totalUtilizationGoal - float64 (c . dedicatedMarkWorkersNeeded )) / float64 (procs )
458
+ c .fractionalUtilizationGoal = (totalUtilizationGoal - float64 (dedicatedMarkWorkersNeeded )) / float64 (procs )
464
459
} else {
465
460
c .fractionalUtilizationGoal = 0
466
461
}
467
462
468
463
// In STW mode, we just want dedicated workers.
469
464
if debug .gcstoptheworld > 0 {
470
- c . dedicatedMarkWorkersNeeded = int64 (procs )
465
+ dedicatedMarkWorkersNeeded = int64 (procs )
471
466
c .fractionalUtilizationGoal = 0
472
467
}
473
468
@@ -482,7 +477,7 @@ func (c *gcControllerState) startCycle(markStartTime int64, procs int, trigger g
482
477
// required. However, we need at least one dedicated mark worker or
483
478
// idle GC worker to ensure GC progress in some scenarios (see comment
484
479
// on maxIdleMarkWorkers).
485
- if c . dedicatedMarkWorkersNeeded > 0 {
480
+ if dedicatedMarkWorkersNeeded > 0 {
486
481
c .setMaxIdleMarkWorkers (0 )
487
482
} else {
488
483
// TODO(mknyszek): The fundamental reason why we need this is because
@@ -492,13 +487,14 @@ func (c *gcControllerState) startCycle(markStartTime int64, procs int, trigger g
492
487
c .setMaxIdleMarkWorkers (1 )
493
488
}
494
489
} else {
495
- // N.B. gomaxprocs and dedicatedMarkWorkersNeeded is guaranteed not to
490
+ // N.B. gomaxprocs and dedicatedMarkWorkersNeeded are guaranteed not to
496
491
// change during a GC cycle.
497
- c .setMaxIdleMarkWorkers (int32 (procs ) - int32 (c . dedicatedMarkWorkersNeeded ))
492
+ c .setMaxIdleMarkWorkers (int32 (procs ) - int32 (dedicatedMarkWorkersNeeded ))
498
493
}
499
494
500
495
// Compute initial values for controls that are updated
501
496
// throughout the cycle.
497
+ c .dedicatedMarkWorkersNeeded .Store (dedicatedMarkWorkersNeeded )
502
498
c .revise ()
503
499
504
500
if debug .gcpacertrace > 0 {
@@ -507,7 +503,7 @@ func (c *gcControllerState) startCycle(markStartTime int64, procs int, trigger g
507
503
" (scan " , gcController .heapScan .Load ()>> 20 , " MB in " ,
508
504
work .initialHeapLive >> 20 , "->" ,
509
505
heapGoal >> 20 , " MB)" ,
510
- " workers=" , c . dedicatedMarkWorkersNeeded ,
506
+ " workers=" , dedicatedMarkWorkersNeeded ,
511
507
"+" , c .fractionalUtilizationGoal , "\n " )
512
508
}
513
509
}
@@ -761,7 +757,7 @@ func (c *gcControllerState) enlistWorker() {
761
757
762
758
// There are no idle Ps. If we need more dedicated workers,
763
759
// try to preempt a running P so it will switch to a worker.
764
- if c .dedicatedMarkWorkersNeeded <= 0 {
760
+ if c .dedicatedMarkWorkersNeeded . Load () <= 0 {
765
761
return
766
762
}
767
763
// Pick a random other P to preempt.
@@ -831,14 +827,14 @@ func (c *gcControllerState) findRunnableGCWorker(pp *p, now int64) (*g, int64) {
831
827
return nil , now
832
828
}
833
829
834
- decIfPositive := func (ptr * int64 ) bool {
830
+ decIfPositive := func (val * atomic. Int64 ) bool {
835
831
for {
836
- v := atomic . Loadint64 ( ptr )
832
+ v := val . Load ( )
837
833
if v <= 0 {
838
834
return false
839
835
}
840
836
841
- if atomic . Casint64 ( ptr , v , v - 1 ) {
837
+ if val . CompareAndSwap ( v , v - 1 ) {
842
838
return true
843
839
}
844
840
}
@@ -905,7 +901,7 @@ func (c *gcControllerState) markWorkerStop(mode gcMarkWorkerMode, duration int64
905
901
switch mode {
906
902
case gcMarkWorkerDedicatedMode :
907
903
c .dedicatedMarkTime .Add (duration )
908
- atomic . Xaddint64 ( & c .dedicatedMarkWorkersNeeded , 1 )
904
+ c .dedicatedMarkWorkersNeeded . Add ( 1 )
909
905
case gcMarkWorkerFractionalMode :
910
906
c .fractionalMarkTime .Add (duration )
911
907
case gcMarkWorkerIdleMode :
0 commit comments