mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
This change modifies the type of several mstats fields to be a new type: sysMemStat. This type has the same structure as the fields used to have. The purpose of this change is to make it very clear which stats may be used in various functions for accounting (usually the platform-specific sys* functions, but there are others). Currently there's an implicit understanding that the *uint64 value passed to these functions is some kind of statistic whose value is atomically managed. This understanding isn't inherently problematic, but we're about to change how some stats (which currently use mSysStatInc and mSysStatDec) work, so we want to make it very clear what the various requirements are around "sysStat". This change also removes mSysStatInc and mSysStatDec in favor of a method on sysMemStat. Note that those two functions were originally written the way they were because atomic 64-bit adds required a valid G on ARM, but this hasn't been the case for a very long time (since golang.org/cl/14204, but even before then it wasn't clear if mutexes required a valid G anymore). Today we implement 64-bit adds on ARM with a spinlock table. Change-Id: I4e9b37cf14afc2ae20cf736e874eb0064af086d7 Reviewed-on: https://go-review.googlesource.com/c/go/+/246971 Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Michael Knyszek <mknyszek@google.com> Reviewed-by: Michael Pratt <mpratt@google.com>
77 lines
1.9 KiB
Go
77 lines
1.9 KiB
Go
// Copyright 2018 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package runtime
|
|
|
|
import (
|
|
"unsafe"
|
|
)
|
|
|
|
// Don't split the stack as this method may be invoked without a valid G, which
|
|
// prevents us from allocating more stack.
|
|
//go:nosplit
|
|
func sysAlloc(n uintptr, sysStat *sysMemStat) unsafe.Pointer {
|
|
p, err := mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
|
|
if err != 0 {
|
|
if err == _EACCES {
|
|
print("runtime: mmap: access denied\n")
|
|
exit(2)
|
|
}
|
|
if err == _EAGAIN {
|
|
print("runtime: mmap: too much locked memory (check 'ulimit -l').\n")
|
|
exit(2)
|
|
}
|
|
return nil
|
|
}
|
|
sysStat.add(int64(n))
|
|
return p
|
|
}
|
|
|
|
func sysUnused(v unsafe.Pointer, n uintptr) {
|
|
madvise(v, n, _MADV_DONTNEED)
|
|
}
|
|
|
|
func sysUsed(v unsafe.Pointer, n uintptr) {
|
|
}
|
|
|
|
func sysHugePage(v unsafe.Pointer, n uintptr) {
|
|
}
|
|
|
|
// Don't split the stack as this function may be invoked without a valid G,
|
|
// which prevents us from allocating more stack.
|
|
//go:nosplit
|
|
func sysFree(v unsafe.Pointer, n uintptr, sysStat *sysMemStat) {
|
|
sysStat.add(-int64(n))
|
|
munmap(v, n)
|
|
|
|
}
|
|
|
|
func sysFault(v unsafe.Pointer, n uintptr) {
|
|
mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE|_MAP_FIXED, -1, 0)
|
|
}
|
|
|
|
func sysReserve(v unsafe.Pointer, n uintptr) unsafe.Pointer {
|
|
p, err := mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, -1, 0)
|
|
if err != 0 {
|
|
return nil
|
|
}
|
|
return p
|
|
}
|
|
|
|
func sysMap(v unsafe.Pointer, n uintptr, sysStat *sysMemStat) {
|
|
sysStat.add(int64(n))
|
|
|
|
// AIX does not allow mapping a range that is already mapped.
|
|
// So, call mprotect to change permissions.
|
|
// Note that sysMap is always called with a non-nil pointer
|
|
// since it transitions a Reserved memory region to Prepared,
|
|
// so mprotect is always possible.
|
|
_, err := mprotect(v, n, _PROT_READ|_PROT_WRITE)
|
|
if err == _ENOMEM {
|
|
throw("runtime: out of memory")
|
|
}
|
|
if err != 0 {
|
|
throw("runtime: cannot map pages in arena address space")
|
|
}
|
|
}
|