@@ -63,13 +63,12 @@ func (gp *g) internalBlocked() bool {
63
63
return reason < waitReasonChanReceiveNilChan || waitReasonSyncWaitGroupWait < reason
64
64
}
65
65
66
+ // allGsSnapshotSortedForGC takes a snapshot of allgs and returns a sorted
67
+ // array of Gs. The array is sorted by the G's status, with running Gs
68
+ // first, followed by blocked Gs. The returned index indicates the cutoff
69
+ // between runnable and blocked Gs.
70
+ //
66
71
// The world must be stopped or allglock must be held.
67
- // go through the snapshot of allgs, putting them into an arrays,
68
- // separated by index, where [0:blockedIndex] contains only running Gs
69
- // allGs[blockedIndex:] contain only blocking Gs
70
- // To avoid GC from marking and scanning the blocked Gs by scanning
71
- // the returned array (which is heap allocated), we mask the highest
72
- // bit of the pointers to Gs with gcBitMask.
73
72
func allGsSnapshotSortedForGC () ([]* g , int ) {
74
73
assertWorldStoppedOrLockHeld (& allglock )
75
74
@@ -1195,7 +1194,11 @@ func gcDrainMarkWorkerFractional(gcw *gcWork) {
1195
1194
gcDrain (gcw , gcDrainFractional | gcDrainUntilPreempt | gcDrainFlushBgCredit )
1196
1195
}
1197
1196
1198
- func gcUpdateMarkrootNext () (uint32 , bool ) {
1197
+ // gcNextMarkRoot safely increments work.markrootNext and returns the
1198
+ // index of the next root job. The returned boolean is true if the root job
1199
+ // is valid, and false if there are no more root jobs to be claimed,
1200
+ // i.e. work.markrootNext >= work.markrootJobs.
1201
+ func gcNextMarkRoot () (uint32 , bool ) {
1199
1202
var success bool
1200
1203
next , jobs := work .markrootNext .Load (), work .markrootJobs .Load ()
1201
1204
@@ -1281,8 +1284,8 @@ func gcDrain(gcw *gcWork, flags gcDrainFlags) {
1281
1284
// Stop if we're preemptible, if someone wants to STW, or if
1282
1285
// someone is calling forEachP.
1283
1286
for ! (gp .preempt && (preemptible || sched .gcwaiting .Load () || pp .runSafePointFn != 0 )) {
1284
- job , success := gcUpdateMarkrootNext ()
1285
- if ! success {
1287
+ job , ok := gcNextMarkRoot ()
1288
+ if ! ok {
1286
1289
break
1287
1290
}
1288
1291
markroot (gcw , job , flushBgCredit )
@@ -1429,8 +1432,8 @@ func gcDrainN(gcw *gcWork, scanWork int64) int64 {
1429
1432
if b = gcw .tryGetObj (); b == 0 {
1430
1433
// Try to do a root job.
1431
1434
if work .markrootNext .Load () < work .markrootJobs .Load () {
1432
- job , success := gcUpdateMarkrootNext ()
1433
- if success {
1435
+ job , ok := gcNextMarkRoot ()
1436
+ if ok {
1434
1437
workFlushed += markroot (gcw , job , false )
1435
1438
continue
1436
1439
}
0 commit comments