mirror of
https://github.com/golang/go
synced 2024-11-17 22:14:43 -07:00
runtime: fix time.Now on Sierra and older
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>
This commit is contained in:
parent
7e054553ad
commit
2d6f941e8c
@ -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}
|
||||
|
@ -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 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 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 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 nt_tsc_base(BP), SI
|
||||
MOVL nt_scale(BP), DI
|
||||
MOVQ nt_ns_base(BP), BX
|
||||
CMPL nt_generation(BP), CX
|
||||
JNE timeloop17
|
||||
|
||||
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 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:
|
||||
|
Loading…
Reference in New Issue
Block a user