Skip to content

Commit f7e34e7

Browse files
committed
runtime: support non-cooperative preemption on windows/arm64
This adds support for injecting asynchronous preemption calls on windows/arm64. This code exactly follows sigctxt.pushCall for POSIX OSes on arm64. Fixes #49759. Change-Id: Id35ff6bc105c1db9d7ed2918d3ecab0e4e9a9431 Reviewed-on: https://go-review.googlesource.com/c/go/+/366735 Trust: Jason A. Donenfeld <[email protected]> Run-TryBot: Jason A. Donenfeld <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Cherry Mui <[email protected]> Reviewed-by: Austin Clements <[email protected]> Reviewed-by: Patrik Nyblom <[email protected]>
1 parent c58243a commit f7e34e7

File tree

1 file changed

+12
-6
lines changed

1 file changed

+12
-6
lines changed

src/runtime/os_windows.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,18 +1306,13 @@ func setThreadCPUProfiler(hz int32) {
13061306
atomic.Store((*uint32)(unsafe.Pointer(&getg().m.profilehz)), uint32(hz))
13071307
}
13081308

1309-
const preemptMSupported = GOARCH != "arm64"
1309+
const preemptMSupported = true
13101310

13111311
// suspendLock protects simultaneous SuspendThread operations from
13121312
// suspending each other.
13131313
var suspendLock mutex
13141314

13151315
func preemptM(mp *m) {
1316-
if !preemptMSupported {
1317-
// TODO: Implement call injection
1318-
return
1319-
}
1320-
13211316
if mp == getg().m {
13221317
throw("self-preempt")
13231318
}
@@ -1412,6 +1407,17 @@ func preemptM(mp *m) {
14121407
*(*uint32)(unsafe.Pointer(sp)) = uint32(c.lr())
14131408
c.set_lr(newpc - 1)
14141409
c.set_ip(targetPC)
1410+
1411+
case "arm64":
1412+
// Push LR. The injected call is responsible
1413+
// for restoring LR. gentraceback is aware of
1414+
// this extra slot. See sigctxt.pushCall in
1415+
// signal_arm64.go.
1416+
sp := c.sp() - 16 // SP needs 16-byte alignment
1417+
c.set_sp(sp)
1418+
*(*uint64)(unsafe.Pointer(sp)) = uint64(c.lr())
1419+
c.set_lr(newpc)
1420+
c.set_ip(targetPC)
14151421
}
14161422
stdcall2(_SetThreadContext, thread, uintptr(unsafe.Pointer(c)))
14171423
}

0 commit comments

Comments
 (0)