]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix time.Now on Sierra and older
authorGiovanni Bajo <rasky@develer.com>
Sat, 13 Jan 2018 01:22:05 +0000 (02:22 +0100)
committerAustin Clements <austin@google.com>
Tue, 16 Jan 2018 16:49:41 +0000 (16:49 +0000)
CL 67332 created the fast no-syscall path for time.Now in High Sierra
but managed to break Sierra and older by forcing them into the slow
syscall path: the version check based on commpage version was wrong.

This CL uses the Darwin version number instead.

The assembly diff is noisy because many variables had to be
renamed, but the only actual change is the version check.

Fixes #23419.

Change-Id: Ie31ef5fb88f66d1517a8693942a7fb6100c213b0
Reviewed-on: https://go-review.googlesource.com/87655
Run-TryBot: Giovanni Bajo <rasky@develer.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
src/runtime/os_darwin.go
src/runtime/sys_darwin_amd64.s

index 4ab5a7637366e6ba669941e623c3decbdbf35072..580dffa1a399d9efa397f3a7c3b73a58ad2742f3 100644 (file)
@@ -11,6 +11,8 @@ type mOS struct {
        waitsema uint32 // semaphore for parking on locks
 }
 
+var darwinVersion int
+
 func bsdthread_create(stk, arg unsafe.Pointer, fn uintptr) int32
 func bsdthread_register() int32
 
@@ -50,16 +52,35 @@ func osinit() {
        // can look at the environment first.
 
        ncpu = getncpu()
-
        physPageSize = getPageSize()
+       darwinVersion = getDarwinVersion()
 }
 
 const (
-       _CTL_HW      = 6
-       _HW_NCPU     = 3
-       _HW_PAGESIZE = 7
+       _CTL_KERN       = 1
+       _CTL_HW         = 6
+       _KERN_OSRELEASE = 2
+       _HW_NCPU        = 3
+       _HW_PAGESIZE    = 7
 )
 
+func getDarwinVersion() int {
+       // Use sysctl to fetch kern.osrelease
+       mib := [2]uint32{_CTL_KERN, _KERN_OSRELEASE}
+       var out [32]byte
+       nout := unsafe.Sizeof(out)
+       ret := sysctl(&mib[0], 2, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
+       if ret >= 0 {
+               ver := 0
+               for i := 0; i < int(nout) && out[i] >= '0' && out[i] <= '9'; i++ {
+                       ver *= 10
+                       ver += int(out[i] - '0')
+               }
+               return ver
+       }
+       return 17 // should not happen: default to a newish version
+}
+
 func getncpu() int32 {
        // Use sysctl to fetch hw.ncpu.
        mib := [2]uint32{_CTL_HW, _HW_NCPU}
index f549efdbf6bb1ebe4becf9e7c474b8675c15512e..ab57843dfaf8d02f1a3ef7352e8c85c00ebbab29 100644 (file)
@@ -122,36 +122,34 @@ TEXT runtime·madvise(SB), NOSPLIT, $0
 // OS X comm page time offsets
 // https://opensource.apple.com/source/xnu/xnu-4570.1.46/osfmk/i386/cpu_capabilities.h
 
-#define        commpage_version        0x1e
-
-#define        v12_nt_tsc_base 0x50
-#define        v12_nt_scale    0x58
-#define        v12_nt_shift    0x5c
-#define        v12_nt_ns_base  0x60
-#define        v12_nt_generation       0x68
-#define        v12_gtod_generation     0x6c  // obsolete since High Sierra (v13)
-#define        v12_gtod_ns_base        0x70  // obsolete since High Sierra (v13)
-#define        v12_gtod_sec_base       0x78  // obsolete since High Sierra (v13)
-
-#define        v13_gtod_ns_base        0xd0
-#define        v13_gtod_sec_ofs        0xd8
-#define        v13_gtod_frac_ofs       0xe0
-#define        v13_gtod_scale          0xe8
-#define        v13_gtod_tkspersec      0xf0
+#define        nt_tsc_base     0x50
+#define        nt_scale        0x58
+#define        nt_shift        0x5c
+#define        nt_ns_base      0x60
+#define        nt_generation   0x68
+#define        gtod_generation 0x6c  // obsolete since Darwin v17 (High Sierra)
+#define        gtod_ns_base    0x70  // obsolete since Darwin v17 (High Sierra)
+#define        gtod_sec_base   0x78  // obsolete since Darwin v17 (High Sierra)
+
+#define        v17_gtod_ns_base        0xd0
+#define        v17_gtod_sec_ofs        0xd8
+#define        v17_gtod_frac_ofs       0xe0
+#define        v17_gtod_scale          0xe8
+#define        v17_gtod_tkspersec      0xf0
 
 TEXT runtime·nanotime(SB),NOSPLIT,$0-8
        MOVQ    $0x7fffffe00000, BP     /* comm page base */
        // Loop trying to take a consistent snapshot
        // of the time parameters.
 timeloop:
-       MOVL    v12_nt_generation(BP), R9
+       MOVL    nt_generation(BP), R9
        TESTL   R9, R9
        JZ      timeloop
        RDTSC
-       MOVQ    v12_nt_tsc_base(BP), R10
-       MOVL    v12_nt_scale(BP), R11
-       MOVQ    v12_nt_ns_base(BP), R12
-       CMPL    v12_nt_generation(BP), R9
+       MOVQ    nt_tsc_base(BP), R10
+       MOVL    nt_scale(BP), R11
+       MOVQ    nt_ns_base(BP), R12
+       CMPL    nt_generation(BP), R9
        JNE     timeloop
 
        // Gathered all the data we need. Compute monotonic time:
@@ -173,32 +171,32 @@ TEXT time·now(SB), NOSPLIT, $32-24
        // are used in the systime fallback, as the timeval address
        // filled in by the system call.
        MOVQ    $0x7fffffe00000, BP     /* comm page base */
-       CMPW    commpage_version(BP), $13
-       JB              v12 /* sierra and older */
+       CMPQ    runtime·darwinVersion(SB), $17
+       JB              legacy /* sierra and older */
 
-       // This is the new code, for macOS High Sierra (v13) and newer.
-v13:
+       // This is the new code, for macOS High Sierra (Darwin v17) and newer.
+v17:
        // Loop trying to take a consistent snapshot
        // of the time parameters.
-timeloop13:
-       MOVQ    v13_gtod_ns_base(BP), R12
+timeloop17:
+       MOVQ    v17_gtod_ns_base(BP), R12
 
-       MOVL    v12_nt_generation(BP), CX
+       MOVL    nt_generation(BP), CX
        TESTL   CX, CX
-       JZ              timeloop13
+       JZ              timeloop17
        RDTSC
-       MOVQ    v12_nt_tsc_base(BP), SI
-       MOVL    v12_nt_scale(BP), DI
-       MOVQ    v12_nt_ns_base(BP), BX
-       CMPL    v12_nt_generation(BP), CX
-       JNE             timeloop13
-
-       MOVQ    v13_gtod_sec_ofs(BP), R8
-       MOVQ    v13_gtod_frac_ofs(BP), R9
-       MOVQ    v13_gtod_scale(BP), R10
-       MOVQ    v13_gtod_tkspersec(BP), R11
-       CMPQ    v13_gtod_ns_base(BP), R12
-       JNE     timeloop13
+       MOVQ    nt_tsc_base(BP), SI
+       MOVL    nt_scale(BP), DI
+       MOVQ    nt_ns_base(BP), BX
+       CMPL    nt_generation(BP), CX
+       JNE             timeloop17
+
+       MOVQ    v17_gtod_sec_ofs(BP), R8
+       MOVQ    v17_gtod_frac_ofs(BP), R9
+       MOVQ    v17_gtod_scale(BP), R10
+       MOVQ    v17_gtod_tkspersec(BP), R11
+       CMPQ    v17_gtod_ns_base(BP), R12
+       JNE     timeloop17
 
        // Compute monotonic time
        //      mono = ((tsc - nt_tsc_base) * nt_scale) >> 32 + nt_ns_base
@@ -240,24 +238,24 @@ timeloop13:
        MOVQ    DX, nsec+8(FP)
        RET
 
-       // This is the legacy code needed for macOS Sierra (v12) and older.
-v12:
+       // This is the legacy code needed for macOS Sierra (Darwin v16) and older.
+legacy:
        // Loop trying to take a consistent snapshot
        // of the time parameters.
 timeloop:
-       MOVL    v12_gtod_generation(BP), R8
-       MOVL    v12_nt_generation(BP), R9
+       MOVL    gtod_generation(BP), R8
+       MOVL    nt_generation(BP), R9
        TESTL   R9, R9
        JZ      timeloop
        RDTSC
-       MOVQ    v12_nt_tsc_base(BP), R10
-       MOVL    v12_nt_scale(BP), R11
-       MOVQ    v12_nt_ns_base(BP), R12
-       CMPL    v12_nt_generation(BP), R9
+       MOVQ    nt_tsc_base(BP), R10
+       MOVL    nt_scale(BP), R11
+       MOVQ    nt_ns_base(BP), R12
+       CMPL    nt_generation(BP), R9
        JNE     timeloop
-       MOVQ    v12_gtod_ns_base(BP), R13
-       MOVQ    v12_gtod_sec_base(BP), R14
-       CMPL    v12_gtod_generation(BP), R8
+       MOVQ    gtod_ns_base(BP), R13
+       MOVQ    gtod_sec_base(BP), R14
+       CMPL    gtod_generation(BP), R8
        JNE     timeloop
 
        // Gathered all the data we need. Compute: