aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/golang-runtime-resume-timers.patch
diff options
context:
space:
mode:
Diffstat (limited to 'golang-runtime-resume-timers.patch')
-rw-r--r--golang-runtime-resume-timers.patch203
1 files changed, 0 insertions, 203 deletions
diff --git a/golang-runtime-resume-timers.patch b/golang-runtime-resume-timers.patch
deleted file mode 100644
index d2a78406..00000000
--- a/golang-runtime-resume-timers.patch
+++ /dev/null
@@ -1,203 +0,0 @@
-From 84b070f6fab474f9e278d9e85b198e1382499b48 Mon Sep 17 00:00:00 2001
-From: "Jason A. Donenfeld" <Jason@zx2c4.com>
-Date: Tue, 27 Aug 2019 06:46:16 -0600
-Subject: [PATCH] [release-branch.go1.13] runtime: monitor for suspend/resume
- to kick timeouts
-
-Starting in Windows 8, the wait functions don't take into account
-suspend time, even though the monotonic counters do. This results in
-timer buckets stalling on resume. Therefore, this commit makes it so
-that on resume, we return from the wait functions and recalculate the
-amount of time left to wait.
-
-This is a cherry pick of CL 191957 and its cleanup, CL 198417.
-
-Updates #31528
-Fixes #34130
-
-Change-Id: I0db02cc72188cb620954e87a0180e0a3c83f4a56
-Reviewed-on: https://go-review.googlesource.com/c/go/+/193607
-Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
-TryBot-Result: Gobot Gobot <gobot@golang.org>
-Reviewed-by: Austin Clements <austin@google.com>
----
- src/runtime/os_windows.go | 81 ++++++++++++++++++++++++++++++----
- src/runtime/syscall_windows.go | 12 +++--
- 2 files changed, 80 insertions(+), 13 deletions(-)
-
-diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go
-index 074ae0f40de..1cd0932eaed 100644
---- a/src/runtime/os_windows.go
-+++ b/src/runtime/os_windows.go
-@@ -49,6 +49,7 @@ const (
- //go:cgo_import_dynamic runtime._VirtualFree VirtualFree%3 "kernel32.dll"
- //go:cgo_import_dynamic runtime._VirtualQuery VirtualQuery%3 "kernel32.dll"
- //go:cgo_import_dynamic runtime._WaitForSingleObject WaitForSingleObject%2 "kernel32.dll"
-+//go:cgo_import_dynamic runtime._WaitForMultipleObjects WaitForMultipleObjects%4 "kernel32.dll"
- //go:cgo_import_dynamic runtime._WriteConsoleW WriteConsoleW%5 "kernel32.dll"
- //go:cgo_import_dynamic runtime._WriteFile WriteFile%5 "kernel32.dll"
-
-@@ -96,6 +97,7 @@ var (
- _VirtualFree,
- _VirtualQuery,
- _WaitForSingleObject,
-+ _WaitForMultipleObjects,
- _WriteConsoleW,
- _WriteFile,
- _ stdFunction
-@@ -139,7 +141,8 @@ func tstart_stdcall(newm *m)
- func ctrlhandler()
-
- type mOS struct {
-- waitsema uintptr // semaphore for parking on locks
-+ waitsema uintptr // semaphore for parking on locks
-+ resumesema uintptr // semaphore to indicate suspend/resume
- }
-
- //go:linkname os_sigpipe os.sigpipe
-@@ -258,6 +261,40 @@ func loadOptionalSyscalls() {
- }
- }
-
-+func monitorSuspendResume() {
-+ const _DEVICE_NOTIFY_CALLBACK = 2
-+ type _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS struct {
-+ callback uintptr
-+ context uintptr
-+ }
-+
-+ powrprof := windowsLoadSystemLib([]byte("powrprof.dll\000"))
-+ if powrprof == 0 {
-+ return // Running on Windows 7, where we don't need it anyway.
-+ }
-+ powerRegisterSuspendResumeNotification := windowsFindfunc(powrprof, []byte("PowerRegisterSuspendResumeNotification\000"))
-+ if powerRegisterSuspendResumeNotification == nil {
-+ return // Running on Windows 7, where we don't need it anyway.
-+ }
-+ var fn interface{} = func(context uintptr, changeType uint32, setting uintptr) uintptr {
-+ for mp := (*m)(atomic.Loadp(unsafe.Pointer(&allm))); mp != nil; mp = mp.alllink {
-+ if mp.resumesema != 0 {
-+ stdcall1(_SetEvent, mp.resumesema)
-+ }
-+ }
-+ return 0
-+ }
-+ params := _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS{
-+ callback: compileCallback(*efaceOf(&fn), true),
-+ }
-+ handle := uintptr(0)
-+ if stdcall3(powerRegisterSuspendResumeNotification, _DEVICE_NOTIFY_CALLBACK,
-+ uintptr(unsafe.Pointer(&params)),
-+ uintptr(unsafe.Pointer(&handle))) != 0 {
-+ throw("PowerRegisterSuspendResumeNotification failure")
-+ }
-+}
-+
- //go:nosplit
- func getLoadLibrary() uintptr {
- return uintptr(unsafe.Pointer(_LoadLibraryW))
-@@ -488,6 +525,10 @@ func goenvs() {
- }
-
- stdcall1(_FreeEnvironmentStringsW, uintptr(strings))
-+
-+ // We call this all the way here, late in init, so that malloc works
-+ // for the callback function this generates.
-+ monitorSuspendResume()
- }
-
- // exiting is set to non-zero when the process is exiting.
-@@ -606,19 +647,32 @@ func semasleep(ns int64) int32 {
- _WAIT_FAILED = 0xFFFFFFFF
- )
-
-- // store ms in ns to save stack space
-+ var result uintptr
- if ns < 0 {
-- ns = _INFINITE
-+ result = stdcall2(_WaitForSingleObject, getg().m.waitsema, uintptr(_INFINITE))
- } else {
-- ns = int64(timediv(ns, 1000000, nil))
-- if ns == 0 {
-- ns = 1
-+ start := nanotime()
-+ elapsed := int64(0)
-+ for {
-+ ms := int64(timediv(ns-elapsed, 1000000, nil))
-+ if ms == 0 {
-+ ms = 1
-+ }
-+ result = stdcall4(_WaitForMultipleObjects, 2,
-+ uintptr(unsafe.Pointer(&[2]uintptr{getg().m.waitsema, getg().m.resumesema})),
-+ 0, uintptr(ms))
-+ if result != _WAIT_OBJECT_0+1 {
-+ // Not a suspend/resume event
-+ break
-+ }
-+ elapsed = nanotime() - start
-+ if elapsed >= ns {
-+ return -1
-+ }
- }
- }
--
-- result := stdcall2(_WaitForSingleObject, getg().m.waitsema, uintptr(ns))
- switch result {
-- case _WAIT_OBJECT_0: //signaled
-+ case _WAIT_OBJECT_0: // Signaled
- return 0
-
- case _WAIT_TIMEOUT:
-@@ -667,6 +721,15 @@ func semacreate(mp *m) {
- throw("runtime.semacreate")
- })
- }
-+ mp.resumesema = stdcall4(_CreateEventA, 0, 0, 0, 0)
-+ if mp.resumesema == 0 {
-+ systemstack(func() {
-+ print("runtime: createevent failed; errno=", getlasterror(), "\n")
-+ throw("runtime.semacreate")
-+ })
-+ stdcall1(_CloseHandle, mp.waitsema)
-+ mp.waitsema = 0
-+ }
- }
-
- // May run with m.p==nil, so write barriers are not allowed. This
-diff --git a/src/runtime/syscall_windows.go b/src/runtime/syscall_windows.go
-index 722a73d108e..0e2fcfb02da 100644
---- a/src/runtime/syscall_windows.go
-+++ b/src/runtime/syscall_windows.go
-@@ -74,16 +74,18 @@ func compileCallback(fn eface, cleanstack bool) (code uintptr) {
- argsize += uintptrSize
- }
-
-- lock(&cbs.lock)
-- defer unlock(&cbs.lock)
-+ lock(&cbs.lock) // We don't unlock this in a defer because this is used from the system stack.
-
- n := cbs.n
- for i := 0; i < n; i++ {
- if cbs.ctxt[i].gobody == fn.data && cbs.ctxt[i].isCleanstack() == cleanstack {
-- return callbackasmAddr(i)
-+ r := callbackasmAddr(i)
-+ unlock(&cbs.lock)
-+ return r
- }
- }
- if n >= cb_max {
-+ unlock(&cbs.lock)
- throw("too many callback functions")
- }
-
-@@ -99,7 +101,9 @@ func compileCallback(fn eface, cleanstack bool) (code uintptr) {
- cbs.ctxt[n] = c
- cbs.n++
-
-- return callbackasmAddr(n)
-+ r := callbackasmAddr(n)
-+ unlock(&cbs.lock)
-+ return r
- }
-
- const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800