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_windows.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_windows.go')
-rw-r--r-- | src/runtime/mem_windows.go | 17 |
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") |