]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: use mach_absolute_time for runtime.nanotime
authorLars Wiegman <lars@namsral.com>
Tue, 17 Jan 2017 10:38:18 +0000 (11:38 +0100)
committerRuss Cox <rsc@golang.org>
Thu, 2 Feb 2017 21:20:40 +0000 (21:20 +0000)
The existing darwin/amd64 implementation of runtime.nanotime returns the
wallclock time, which results in timers not functioning properly when
system time runs backwards. By implementing the algorithm used by the
darwin syscall mach_absolute_time, timers will function as expected.

The algorithm is described at
https://opensource.apple.com/source/xnu/xnu-3248.60.10/libsyscall/wrappers/mach_absolute_time.s

Fixes #17610

Change-Id: I9c8d35240d48249a6837dca1111b1406e2686f67
Reviewed-on: https://go-review.googlesource.com/35292
Reviewed-by: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/runtime/sys_darwin_amd64.s

index 96fa5b97102378abf00170aa46dce9d9b919fa08..e68dafe6a6cafb07fd31a17a9b24124d283de0ca 100644 (file)
@@ -117,6 +117,27 @@ TEXT runtime·madvise(SB), NOSPLIT, $0
 #define        gtod_ns_base    0x70
 #define        gtod_sec_base   0x78
 
+TEXT monotonictime<>(SB), NOSPLIT, $32
+       MOVQ $0x7fffffe00000, SI // comm page base
+
+timeloop:
+       MOVL  nt_generation(SI), R8
+       TESTL R8, R8
+       JZ    timeloop
+       RDTSC
+       SHLQ  $32, DX
+       ORQ   DX, AX
+       MOVL nt_shift(SI), CX
+       SUBQ nt_tsc_base(SI), AX
+       SHLQ CX, AX
+       MOVL nt_scale(SI), CX
+       MULQ CX
+       SHRQ $32, AX:DX
+       ADDQ nt_ns_base(SI), AX
+       CMPL nt_generation(SI), R8
+       JNE  timeloop
+       RET
+
 TEXT nanotime<>(SB), NOSPLIT, $32
        MOVQ    $0x7fffffe00000, BP     /* comm page base */
        // Loop trying to take a consistent snapshot
@@ -173,7 +194,7 @@ inreg:
        RET
 
 TEXT runtime·nanotime(SB),NOSPLIT,$0-8
-       CALL    nanotime<>(SB)
+       CALL    monotonictime<>(SB)
        MOVQ    AX, ret+0(FP)
        RET