aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/mem_linux.go
diff options
context:
space:
mode:
authorSrdjan Petrovic <spetrovic@google.com>2015-04-16 14:32:18 -0700
committerDavid Crawshaw <crawshaw@golang.org>2015-04-24 16:53:26 +0000
commit6ad33be2d9d6b24aa741b3007a4bcd52db222c41 (patch)
tree904764e1cb4fcf37f7bd4022c43eae35d45b6bfb /src/runtime/mem_linux.go
parent8566979972d51236c37b2823d2c0d52c6efe5406 (diff)
downloadgo-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.go17
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 {