]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: remove slow time compatibility hacks for wine
authorJason A. Donenfeld <Jason@zx2c4.com>
Sat, 24 Aug 2019 15:13:33 +0000 (17:13 +0200)
committerJason A. Donenfeld <Jason@zx2c4.com>
Thu, 29 Aug 2019 13:57:31 +0000 (13:57 +0000)
A few years ago, Wine-specific detection was added as an ugly hack to
work around shortcomings in the emulation layer. Probably it's best to
not special case this emulator versus that emulator versus the real
deal, but there were two arguments presented in the hack's favor:

  1. Wine is useful and developers will appreciate being able to debug
     stuff with it.

  2. The existing KUSER_SHARED_DATA technique for gathering time is
     undocumented, and we shouldn't be relying on it anyway, since
     Microsoft might remove it without notice.

As it turns out, neither one of these are, at the time of writing, true.
(1) has been handled for some time by Wine with the introduction of the
commit entitled "ntdll: Create thread to update user_shared_data time
values when necessary". And (2) is in fact documented:
https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/ntddk/ns-ntddk-kuser_shared_data
https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/-kuser
It's in use so widely by both third-party software (such as games, a
massive market segment) and by Microsoft binaries that removing it from
the operating system will basically never happen.

So with both issues taken care of, this commit simply gets rid of the
old hack.

Change-Id: I80093f50e0d10d53648128d0f9dd76b1b92a119e
Reviewed-on: https://go-review.googlesource.com/c/go/+/191759
Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@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

index 9540069e11a75fa5d5b6fa0c522a6a2e4a89d0ab..60c55cf32540b08051c92b17e001199712aa4abe 100644 (file)
@@ -75,12 +75,10 @@ var (
        _GetStdHandle,
        _GetSystemDirectoryA,
        _GetSystemInfo,
-       _GetSystemTimeAsFileTime,
        _GetThreadContext,
        _LoadLibraryW,
        _LoadLibraryA,
        _QueryPerformanceCounter,
-       _QueryPerformanceFrequency,
        _ResumeThread,
        _SetConsoleCtrlHandler,
        _SetErrorMode,
@@ -251,11 +249,6 @@ func loadOptionalSyscalls() {
        if _WSAGetOverlappedResult == nil {
                throw("WSAGetOverlappedResult not found")
        }
-
-       if windowsFindfunc(n32, []byte("wine_get_version\000")) != nil {
-               // running on Wine
-               initWine(k32)
-       }
 }
 
 //go:nosplit
@@ -379,77 +372,6 @@ func osinit() {
 
 func nanotime() int64
 
-// useQPCTime controls whether time.now and nanotime use QueryPerformanceCounter.
-// This is only set to 1 when running under Wine.
-var useQPCTime uint8
-
-var qpcStartCounter int64
-var qpcMultiplier int64
-
-//go:nosplit
-func nanotimeQPC() int64 {
-       var counter int64 = 0
-       stdcall1(_QueryPerformanceCounter, uintptr(unsafe.Pointer(&counter)))
-
-       // returns number of nanoseconds
-       return (counter - qpcStartCounter) * qpcMultiplier
-}
-
-//go:nosplit
-func nowQPC() (sec int64, nsec int32, mono int64) {
-       var ft int64
-       stdcall1(_GetSystemTimeAsFileTime, uintptr(unsafe.Pointer(&ft)))
-
-       t := (ft - 116444736000000000) * 100
-
-       sec = t / 1000000000
-       nsec = int32(t - sec*1000000000)
-
-       mono = nanotimeQPC()
-       return
-}
-
-func initWine(k32 uintptr) {
-       _GetSystemTimeAsFileTime = windowsFindfunc(k32, []byte("GetSystemTimeAsFileTime\000"))
-       if _GetSystemTimeAsFileTime == nil {
-               throw("could not find GetSystemTimeAsFileTime() syscall")
-       }
-
-       _QueryPerformanceCounter = windowsFindfunc(k32, []byte("QueryPerformanceCounter\000"))
-       _QueryPerformanceFrequency = windowsFindfunc(k32, []byte("QueryPerformanceFrequency\000"))
-       if _QueryPerformanceCounter == nil || _QueryPerformanceFrequency == nil {
-               throw("could not find QPC syscalls")
-       }
-
-       // We can not simply fallback to GetSystemTimeAsFileTime() syscall, since its time is not monotonic,
-       // instead we use QueryPerformanceCounter family of syscalls to implement monotonic timer
-       // https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx
-
-       var tmp int64
-       stdcall1(_QueryPerformanceFrequency, uintptr(unsafe.Pointer(&tmp)))
-       if tmp == 0 {
-               throw("QueryPerformanceFrequency syscall returned zero, running on unsupported hardware")
-       }
-
-       // This should not overflow, it is a number of ticks of the performance counter per second,
-       // its resolution is at most 10 per usecond (on Wine, even smaller on real hardware), so it will be at most 10 millions here,
-       // panic if overflows.
-       if tmp > (1<<31 - 1) {
-               throw("QueryPerformanceFrequency overflow 32 bit divider, check nosplit discussion to proceed")
-       }
-       qpcFrequency := int32(tmp)
-       stdcall1(_QueryPerformanceCounter, uintptr(unsafe.Pointer(&qpcStartCounter)))
-
-       // Since we are supposed to run this time calls only on Wine, it does not lose precision,
-       // since Wine's timer is kind of emulated at 10 Mhz, so it will be a nice round multiplier of 100
-       // but for general purpose system (like 3.3 Mhz timer on i7) it will not be very precise.
-       // We have to do it this way (or similar), since multiplying QPC counter by 100 millions overflows
-       // int64 and resulted time will always be invalid.
-       qpcMultiplier = int64(timediv(1000000000, qpcFrequency, nil))
-
-       useQPCTime = 1
-}
-
 //go:nosplit
 func getRandomData(r []byte) {
        n := 0
index 761da8eaef1a4d8313bd9e8b43ba91bff7f91ddb..b8a8ad865bb0a14d9f390d64b6f2f62bf885c99c 100644 (file)
@@ -445,8 +445,6 @@ TEXT runtime·switchtothread(SB),NOSPLIT,$0
 #define time_hi2 8
 
 TEXT runtime·nanotime(SB),NOSPLIT,$0-8
-       CMPB    runtime·useQPCTime(SB), $0
-       JNE     useQPC
 loop:
        MOVL    (_INTERRUPT_TIME+time_hi1), AX
        MOVL    (_INTERRUPT_TIME+time_lo), CX
@@ -463,13 +461,8 @@ loop:
        MOVL    AX, ret_lo+0(FP)
        MOVL    DX, ret_hi+4(FP)
        RET
-useQPC:
-       JMP     runtime·nanotimeQPC(SB)
-       RET
 
 TEXT time·now(SB),NOSPLIT,$0-20
-       CMPB    runtime·useQPCTime(SB), $0
-       JNE     useQPC
 loop:
        MOVL    (_INTERRUPT_TIME+time_hi1), AX
        MOVL    (_INTERRUPT_TIME+time_lo), CX
@@ -538,6 +531,3 @@ wall:
        MOVL    AX, sec+0(FP)
        MOVL    DX, sec+4(FP)
        RET
-useQPC:
-       JMP     runtime·nowQPC(SB)
-       RET
index 2aea8eaff7ec15eb93d84fe39ebe2701a4c48b06..d62fd411b1214c3da136e36c58ae6eca0cc37d31 100644 (file)
@@ -474,8 +474,6 @@ TEXT runtime·switchtothread(SB),NOSPLIT|NOFRAME,$0
 #define time_hi2 8
 
 TEXT runtime·nanotime(SB),NOSPLIT,$0-8
-       CMPB    runtime·useQPCTime(SB), $0
-       JNE     useQPC
        MOVQ    $_INTERRUPT_TIME, DI
 loop:
        MOVL    time_hi1(DI), AX
@@ -488,13 +486,8 @@ loop:
        IMULQ   $100, CX
        MOVQ    CX, ret+0(FP)
        RET
-useQPC:
-       JMP     runtime·nanotimeQPC(SB)
-       RET
 
 TEXT time·now(SB),NOSPLIT,$0-24
-       CMPB    runtime·useQPCTime(SB), $0
-       JNE     useQPC
        MOVQ    $_INTERRUPT_TIME, DI
 loop:
        MOVL    time_hi1(DI), AX
@@ -534,6 +527,3 @@ wall:
        SUBQ    DX, CX
        MOVL    CX, nsec+8(FP)
        RET
-useQPC:
-       JMP     runtime·nowQPC(SB)
-       RET
index 8f8af0a4f7ec5f668441a2817807043f03fd59e7..294e217e6c6406e5d6f3184a549c974642badcf5 100644 (file)
@@ -496,10 +496,6 @@ TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0
 #define time_hi2 8
 
 TEXT runtime·nanotime(SB),NOSPLIT,$0-8
-       MOVW    $0, R0
-       MOVB    runtime·useQPCTime(SB), R0
-       CMP     $0, R0
-       BNE     useQPC
        MOVW    $_INTERRUPT_TIME, R3
 loop:
        MOVW    time_hi1(R3), R1
@@ -517,15 +513,8 @@ loop:
        MOVW    R3, ret_lo+0(FP)
        MOVW    R4, ret_hi+4(FP)
        RET
-useQPC:
-       B       runtime·nanotimeQPC(SB)                // tail call
-       RET
 
 TEXT time·now(SB),NOSPLIT,$0-20
-       MOVW    $0, R0
-       MOVB    runtime·useQPCTime(SB), R0
-       CMP     $0, R0
-       BNE     useQPC
        MOVW    $_INTERRUPT_TIME, R3
 loop:
        MOVW    time_hi1(R3), R1
@@ -594,9 +583,6 @@ wall:
        MOVW    R7,sec_hi+4(FP)
        MOVW    R1,nsec+8(FP)
        RET
-useQPC:
-       B       runtime·nanotimeQPC(SB)                // tail call
-       RET
 
 // save_g saves the g register (R10) into thread local memory
 // so that we can call externally compiled