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>
diff --git a/src/runtime/malloc.go b/src/runtime/malloc.go
index 4a2d3e3..5896e74 100644
--- a/src/runtime/malloc.go
+++ b/src/runtime/malloc.go
@@ -790,7 +790,7 @@
// There is no associated free operation.
// Intended for things like function/type/debug-related persistent data.
// If align is 0, uses default align (currently 8).
-func persistentalloc(size, align uintptr, stat *uint64) unsafe.Pointer {
+func persistentalloc(size, align uintptr, sysStat *uint64) unsafe.Pointer {
const (
chunk = 256 << 10
maxBlock = 64 << 10 // VM reservation granularity is 64K on windows
@@ -811,7 +811,7 @@
}
if size >= maxBlock {
- return sysAlloc(size, stat)
+ return sysAlloc(size, sysStat)
}
mp := acquirem()
@@ -840,9 +840,9 @@
unlock(&globalAlloc.mutex)
}
- if stat != &memstats.other_sys {
- xadd64(stat, int64(size))
- xadd64(&memstats.other_sys, -int64(size))
+ if sysStat != &memstats.other_sys {
+ mSysStatInc(sysStat, size)
+ mSysStatDec(&memstats.other_sys, size)
}
return p
}