diff options
author | Srdjan Petrovic <spetrovic@google.com> | 2015-04-16 14:32:18 -0700 |
---|---|---|
committer | David Crawshaw <crawshaw@golang.org> | 2015-04-24 16:53:26 +0000 |
commit | 6ad33be2d9d6b24aa741b3007a4bcd52db222c41 (patch) | |
tree | 904764e1cb4fcf37f7bd4022c43eae35d45b6bfb /src/runtime/mem_linux.go | |
parent | 8566979972d51236c37b2823d2c0d52c6efe5406 (diff) | |
download | go-6ad33be2d9d6b24aa741b3007a4bcd52db222c41.tar.gz go-6ad33be2d9d6b24aa741b3007a4bcd52db222c41.zip |
runtime: implement xadduintptr and update system mstats using it
The motivation is that sysAlloc/Free() currently aren't safe to be
called without a valid G, because arm's xadd64() uses locks that require
a valid G.
The solution here was proposed by Dmitry Vyukov: use xadduintptr()
instead of xadd64(), until arm can support xadd64 on all of its
architectures (not a trivial task for arm).
Change-Id: I250252079357ea2e4360e1235958b1c22051498f
Reviewed-on: https://go-review.googlesource.com/9002
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Diffstat (limited to 'src/runtime/mem_linux.go')
-rw-r--r-- | src/runtime/mem_linux.go | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/src/runtime/mem_linux.go b/src/runtime/mem_linux.go index a78a03ee5c..f988e75a17 100644 --- a/src/runtime/mem_linux.go +++ b/src/runtime/mem_linux.go @@ -48,8 +48,10 @@ func mmap_fixed(v unsafe.Pointer, n uintptr, prot, flags, fd int32, offset uint3 return p } +// 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, stat *uint64) unsafe.Pointer { +func sysAlloc(n uintptr, sysStat *uint64) unsafe.Pointer { p := mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0) if uintptr(p) < 4096 { if uintptr(p) == _EACCES { @@ -62,7 +64,7 @@ func sysAlloc(n uintptr, stat *uint64) unsafe.Pointer { } return nil } - xadd64(stat, int64(n)) + mSysStatInc(sysStat, n) return p } @@ -93,8 +95,11 @@ func sysUsed(v unsafe.Pointer, n uintptr) { } } -func sysFree(v unsafe.Pointer, n uintptr, stat *uint64) { - xadd64(stat, -int64(n)) +// 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 *uint64) { + mSysStatDec(sysStat, n) munmap(v, n) } @@ -128,8 +133,8 @@ func sysReserve(v unsafe.Pointer, n uintptr, reserved *bool) unsafe.Pointer { return p } -func sysMap(v unsafe.Pointer, n uintptr, reserved bool, stat *uint64) { - xadd64(stat, int64(n)) +func sysMap(v unsafe.Pointer, n uintptr, reserved bool, sysStat *uint64) { + mSysStatInc(sysStat, n) // On 64-bit, we don't actually have v reserved, so tread carefully. if !reserved { |