]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: implement high resolution timer on windows arm/arm64
authorqmuntal <quimmuntal@gmail.com>
Fri, 24 Feb 2023 17:15:32 +0000 (18:15 +0100)
committerGopher Robot <gobot@golang.org>
Mon, 13 Mar 2023 14:20:41 +0000 (14:20 +0000)
This CL moves the usleep2HighRes from assembly to good old Go.
This is safe because since CL 288793 usleep is always called with
a g, else one wold have to call usleep_no_g. This condition was
not enforced when high resolution timers were first implemented
on Windows (CL 248699), so the implementation was done in assembly.

Other than removing a bunch of obscure assembly code, this CL makes
high resolution timers work on windows arm/arm64 by free, as the
system calls are the same in all windows platforms.

Change-Id: I41ecf78026fd7e11e85258a411ae074a77e8c7fc
Reviewed-on: https://go-review.googlesource.com/c/go/+/471142
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
Run-TryBot: Quim Muntal <quimmuntal@gmail.com>

src/runtime/os_windows.go
src/runtime/sys_windows_386.s
src/runtime/sys_windows_amd64.s
src/runtime/sys_windows_arm.s
src/runtime/sys_windows_arm64.s

index 62509df03081717b05fde13bfe212d0fb139debf..40e7aade1e6c5dbdb13cebeff4f24c0cf78ab57c 100644 (file)
@@ -440,13 +440,7 @@ func createHighResTimer() uintptr {
                _SYNCHRONIZE|_TIMER_QUERY_STATE|_TIMER_MODIFY_STATE)
 }
 
-const highResTimerSupported = GOARCH == "386" || GOARCH == "amd64"
-
 func initHighResTimer() {
-       if !highResTimerSupported {
-               // TODO: Not yet implemented.
-               return
-       }
        h := createHighResTimer()
        if h != 0 {
                haveHighResTimer = true
@@ -1130,7 +1124,6 @@ func stdcall7(fn stdFunction, a0, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
 
 // These must run on the system stack only.
 func usleep2(dt int32)
-func usleep2HighRes(dt int32)
 func switchtothread()
 
 //go:nosplit
@@ -1152,13 +1145,15 @@ func usleep_no_g(us uint32) {
 //go:nosplit
 func usleep(us uint32) {
        systemstack(func() {
-               dt := -10 * int32(us) // relative sleep (negative), 100ns units
+               dt := -10 * int64(us) // relative sleep (negative), 100ns units
                // If the high-res timer is available and its handle has been allocated for this m, use it.
                // Otherwise fall back to the low-res one, which doesn't need a handle.
                if haveHighResTimer && getg().m.highResTimer != 0 {
-                       usleep2HighRes(dt)
+                       h := getg().m.highResTimer
+                       stdcall6(_SetWaitableTimer, h, uintptr(unsafe.Pointer(&dt)), 0, 0, 0, 0)
+                       stdcall3(_NtWaitForSingleObject, h, 0, 0)
                } else {
-                       usleep2(dt)
+                       usleep2(int32(dt))
                }
        })
 }
index 818f1b4d7982c3787b16a651a9005e7b1b0a5444..f5ce977f36c4aa63d329411e0429cf78ecad635b 100644 (file)
@@ -241,43 +241,6 @@ TEXT runtime·usleep2(SB),NOSPLIT,$20-4
        MOVL    BP, SP
        RET
 
-// Runs on OS stack.
-// duration (in -100ns units) is in dt+0(FP).
-// g is valid.
-TEXT runtime·usleep2HighRes(SB),NOSPLIT,$36-4
-       MOVL    dt+0(FP), BX
-       MOVL    $-1, hi-4(SP)
-       MOVL    BX, lo-8(SP)
-
-       get_tls(CX)
-       MOVL    g(CX), CX
-       MOVL    g_m(CX), CX
-       MOVL    (m_mOS+mOS_highResTimer)(CX), CX
-       MOVL    CX, saved_timer-12(SP)
-
-       MOVL    $0, fResume-16(SP)
-       MOVL    $0, lpArgToCompletionRoutine-20(SP)
-       MOVL    $0, pfnCompletionRoutine-24(SP)
-       MOVL    $0, lPeriod-28(SP)
-       LEAL    lo-8(SP), BX
-       MOVL    BX, lpDueTime-32(SP)
-       MOVL    CX, hTimer-36(SP)
-       MOVL    SP, BP
-       MOVL    runtime·_SetWaitableTimer(SB), AX
-       CALL    AX
-       MOVL    BP, SP
-
-       MOVL    $0, ptime-28(SP)
-       MOVL    $0, alertable-32(SP)
-       MOVL    saved_timer-12(SP), CX
-       MOVL    CX, handle-36(SP)
-       MOVL    SP, BP
-       MOVL    runtime·_NtWaitForSingleObject(SB), AX
-       CALL    AX
-       MOVL    BP, SP
-
-       RET
-
 // Runs on OS stack.
 TEXT runtime·switchtothread(SB),NOSPLIT,$0
        MOVL    SP, BP
index 5eb03b014ed37c5927f63493f1c551ed8ff1cfb5..367cb2ba766e7ecafe72041c11a8e8114f1650af 100644 (file)
@@ -251,39 +251,6 @@ TEXT runtime·usleep2(SB),NOSPLIT,$48-4
        MOVQ    40(SP), SP
        RET
 
-// Runs on OS stack. duration (in -100ns units) is in dt+0(FP).
-// g is valid.
-TEXT runtime·usleep2HighRes(SB),NOSPLIT,$72-4
-       MOVLQSX dt+0(FP), BX
-       get_tls(CX)
-
-       MOVQ    SP, AX
-       ANDQ    $~15, SP        // alignment as per Windows requirement
-       MOVQ    AX, 64(SP)
-
-       MOVQ    g(CX), CX
-       MOVQ    g_m(CX), CX
-       MOVQ    (m_mOS+mOS_highResTimer)(CX), CX        // hTimer
-       MOVQ    CX, 48(SP)                              // save hTimer for later
-       LEAQ    56(SP), DX                              // lpDueTime
-       MOVQ    BX, (DX)
-       MOVQ    $0, R8                                  // lPeriod
-       MOVQ    $0, R9                                  // pfnCompletionRoutine
-       MOVQ    $0, AX
-       MOVQ    AX, 32(SP)                              // lpArgToCompletionRoutine
-       MOVQ    AX, 40(SP)                              // fResume
-       MOVQ    runtime·_SetWaitableTimer(SB), AX
-       CALL    AX
-
-       MOVQ    48(SP), CX                              // handle
-       MOVQ    $0, DX                                  // alertable
-       MOVQ    $0, R8                                  // ptime
-       MOVQ    runtime·_NtWaitForSingleObject(SB), AX
-       CALL    AX
-
-       MOVQ    64(SP), SP
-       RET
-
 // Runs on OS stack.
 TEXT runtime·switchtothread(SB),NOSPLIT,$0
        MOVQ    SP, AX
index 0af19db352ceabb5d034d22696a95c2057910809..67009df723df576e5e18b23b520622279bab3883 100644 (file)
@@ -211,13 +211,6 @@ TEXT runtime·usleep2(SB),NOSPLIT|NOFRAME,$0-4
        MOVW    R4, R13                 // Restore SP
        MOVM.IA.W (R13), [R4, R15]      // pop {R4, pc}
 
-// Runs on OS stack.
-// duration (in -100ns units) is in dt+0(FP).
-// g is valid.
-// TODO: needs to be implemented properly.
-TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$0-4
-       B       runtime·abort(SB)
-
 // Runs on OS stack.
 TEXT runtime·switchtothread(SB),NOSPLIT|NOFRAME,$0
        MOVM.DB.W [R4, R14], (R13)      // push {R4, lr}
index 6da866ac889a7884f006ed3480a09105ae9d2ddd..1161ad013234d6d274aca732bb7c03eb684b316f 100644 (file)
@@ -239,13 +239,6 @@ TEXT runtime·usleep2(SB),NOSPLIT,$32-4
        ADD     $16, RSP
        RET
 
-// Runs on OS stack.
-// duration (in -100ns units) is in dt+0(FP).
-// g is valid.
-// TODO: needs to be implemented properly.
-TEXT runtime·usleep2HighRes(SB),NOSPLIT|NOFRAME,$0-4
-       B       runtime·abort(SB)
-
 // Runs on OS stack.
 TEXT runtime·switchtothread(SB),NOSPLIT,$16-0
        MOVD    runtime·_SwitchToThread(SB), R0