aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/mem_windows.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_windows.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_windows.go')
-rw-r--r--src/runtime/mem_windows.go17
1 files changed, 11 insertions, 6 deletions
diff --git a/src/runtime/mem_windows.go b/src/runtime/mem_windows.go
index a800ccae1d..42aa7fb4eb 100644
--- a/src/runtime/mem_windows.go
+++ b/src/runtime/mem_windows.go
@@ -18,9 +18,11 @@ const (
_PAGE_NOACCESS = 0x0001
)
+// 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 sysAlloc(n uintptr, stat *uint64) unsafe.Pointer {
- xadd64(stat, int64(n))
+func sysAlloc(n uintptr, sysStat *uint64) unsafe.Pointer {
+ mSysStatInc(sysStat, n)
return unsafe.Pointer(stdcall4(_VirtualAlloc, 0, n, _MEM_COMMIT|_MEM_RESERVE, _PAGE_READWRITE))
}
@@ -74,8 +76,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)
r := stdcall3(_VirtualFree, uintptr(v), 0, _MEM_RELEASE)
if r == 0 {
throw("runtime: failed to release pages")
@@ -100,8 +105,8 @@ func sysReserve(v unsafe.Pointer, n uintptr, reserved *bool) unsafe.Pointer {
return unsafe.Pointer(stdcall4(_VirtualAlloc, 0, n, _MEM_RESERVE, _PAGE_READWRITE))
}
-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)
p := stdcall4(_VirtualAlloc, uintptr(v), n, _MEM_COMMIT, _PAGE_READWRITE)
if p != uintptr(v) {
throw("runtime: cannot map pages in arena address space")