type mstats … var memstats … type MemStats … func init() { … } // ReadMemStats populates m with memory allocator statistics. // // The returned memory allocator statistics are up to date as of the // call to ReadMemStats. This is in contrast with a heap profile, // which is a snapshot as of the most recently completed garbage // collection cycle. func ReadMemStats(m *MemStats) { … } var doubleCheckReadMemStats … // readmemstats_m populates stats for internal runtime values. // // The world must be stopped. func readmemstats_m(stats *MemStats) { … } //go:linkname readGCStats runtime/debug.readGCStats func readGCStats(pauses *[]uint64) { … } // readGCStats_m must be called on the system stack because it acquires the heap // lock. See mheap for details. // //go:systemstack func readGCStats_m(pauses *[]uint64) { … } // flushmcache flushes the mcache of allp[i]. // // The world must be stopped. // //go:nowritebarrier func flushmcache(i int) { … } // flushallmcaches flushes the mcaches of all Ps. // // The world must be stopped. // //go:nowritebarrier func flushallmcaches() { … } type sysMemStat … // load atomically reads the value of the stat. // // Must be nosplit as it is called in runtime initialization, e.g. newosproc0. // //go:nosplit func (s *sysMemStat) load() uint64 { … } // add atomically adds the sysMemStat by n. // // Must be nosplit as it is called in runtime initialization, e.g. newosproc0. // //go:nosplit func (s *sysMemStat) add(n int64) { … } type heapStatsDelta … // merge adds in the deltas from b into a. func (a *heapStatsDelta) merge(b *heapStatsDelta) { … } type consistentHeapStats … // acquire returns a heapStatsDelta to be updated. In effect, // it acquires the shard for writing. release must be called // as soon as the relevant deltas are updated. // // The returned heapStatsDelta must be updated atomically. // // The caller's P must not change between acquire and // release. This also means that the caller should not // acquire a P or release its P in between. A P also must // not acquire a given consistentHeapStats if it hasn't // yet released it. // // nosplit because a stack growth in this function could // lead to a stack allocation that could reenter the // function. // //go:nosplit func (m *consistentHeapStats) acquire() *heapStatsDelta { … } // release indicates that the writer is done modifying // the delta. The value returned by the corresponding // acquire must no longer be accessed or modified after // release is called. // // The caller's P must not change between acquire and // release. This also means that the caller should not // acquire a P or release its P in between. // // nosplit because a stack growth in this function could // lead to a stack allocation that causes another acquire // before this operation has completed. // //go:nosplit func (m *consistentHeapStats) release() { … } // unsafeRead aggregates the delta for this shard into out. // // Unsafe because it does so without any synchronization. The // world must be stopped. func (m *consistentHeapStats) unsafeRead(out *heapStatsDelta) { … } // unsafeClear clears the shard. // // Unsafe because the world must be stopped and values should // be donated elsewhere before clearing. func (m *consistentHeapStats) unsafeClear() { … } // read takes a globally consistent snapshot of m // and puts the aggregated value in out. Even though out is a // heapStatsDelta, the resulting values should be complete and // valid statistic values. // // Not safe to call concurrently. The world must be stopped // or metricsSema must be held. func (m *consistentHeapStats) read(out *heapStatsDelta) { … } type cpuStats … // accumulateGCPauseTime add dt*stwProcs to the GC CPU pause time stats. dt should be // the actual time spent paused, for orthogonality. maxProcs should be GOMAXPROCS, // not work.stwprocs, since this number must be comparable to a total time computed // from GOMAXPROCS. func (s *cpuStats) accumulateGCPauseTime(dt int64, maxProcs int32) { … } // accumulate takes a cpuStats and adds in the current state of all GC CPU // counters. // // gcMarkPhase indicates that we're in the mark phase and that certain counter // values should be used. func (s *cpuStats) accumulate(now int64, gcMarkPhase bool) { … }