gcpercent = 100000
}
live := atomic.Load64(&memstats.heap_live)
+ scan := atomic.Load64(&memstats.heap_scan)
// Assume we're under the soft goal. Pace GC to complete at
// next_gc assuming the heap is in steady-state.
//
// (This is a float calculation to avoid overflowing on
// 100*heap_scan.)
- scanWorkExpected := int64(float64(memstats.heap_scan) * 100 / float64(100+gcpercent))
+ scanWorkExpected := int64(float64(scan) * 100 / float64(100+gcpercent))
if live > memstats.next_gc || c.scanWork > scanWorkExpected {
// We're past the soft goal, or we've already done more scan
heapGoal = int64(float64(memstats.next_gc) * maxOvershoot)
// Compute the upper bound on the scan work remaining.
- scanWorkExpected = int64(memstats.heap_scan)
+ scanWorkExpected = int64(scan)
}
// Compute the remaining scan work estimate.
throw("mheap.allocSpan called with no P")
}
}
- memstats.heap_scan += uint64(c.local_scan)
+ atomic.Xadd64(&memstats.heap_scan, int64(c.local_scan))
c.local_scan = 0
memstats.tinyallocs += uint64(c.local_tinyallocs)
c.local_tinyallocs = 0
systemstack(func() {
c := getg().m.p.ptr().mcache
lock(&h.lock)
- memstats.heap_scan += uint64(c.local_scan)
+ atomic.Xadd64(&memstats.heap_scan, int64(c.local_scan))
c.local_scan = 0
memstats.tinyallocs += uint64(c.local_tinyallocs)
c.local_tinyallocs = 0
// no-scan objects and no-scan tails of objects.
//
// Whenever this is updated, call gcController.revise().
+ //
+ // Read and written atomically or with the world stopped.
heap_scan uint64
// heap_marked is the number of bytes marked by the previous
func purgecachedstats(c *mcache) {
// Protected by either heap or GC lock.
h := &mheap_
- memstats.heap_scan += uint64(c.local_scan)
+ atomic.Xadd64(&memstats.heap_scan, int64(c.local_scan))
c.local_scan = 0
memstats.tinyallocs += uint64(c.local_tinyallocs)
c.local_tinyallocs = 0