Skip to content

Commit 2d6f941

Browse files
raskyaclements
authored andcommitted
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Austin Clements <[email protected]>
1 parent 7e05455 commit 2d6f941

File tree

2 files changed

+75
-56
lines changed

2 files changed

+75
-56
lines changed

src/runtime/os_darwin.go

+25-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ type mOS struct {
1111
waitsema uint32 // semaphore for parking on locks
1212
}
1313

14+
var darwinVersion int
15+
1416
func bsdthread_create(stk, arg unsafe.Pointer, fn uintptr) int32
1517
func bsdthread_register() int32
1618

@@ -50,16 +52,35 @@ func osinit() {
5052
// can look at the environment first.
5153

5254
ncpu = getncpu()
53-
5455
physPageSize = getPageSize()
56+
darwinVersion = getDarwinVersion()
5557
}
5658

5759
const (
58-
_CTL_HW = 6
59-
_HW_NCPU = 3
60-
_HW_PAGESIZE = 7
60+
_CTL_KERN = 1
61+
_CTL_HW = 6
62+
_KERN_OSRELEASE = 2
63+
_HW_NCPU = 3
64+
_HW_PAGESIZE = 7
6165
)
6266

67+
func getDarwinVersion() int {
68+
// Use sysctl to fetch kern.osrelease
69+
mib := [2]uint32{_CTL_KERN, _KERN_OSRELEASE}
70+
var out [32]byte
71+
nout := unsafe.Sizeof(out)
72+
ret := sysctl(&mib[0], 2, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
73+
if ret >= 0 {
74+
ver := 0
75+
for i := 0; i < int(nout) && out[i] >= '0' && out[i] <= '9'; i++ {
76+
ver *= 10
77+
ver += int(out[i] - '0')
78+
}
79+
return ver
80+
}
81+
return 17 // should not happen: default to a newish version
82+
}
83+
6384
func getncpu() int32 {
6485
// Use sysctl to fetch hw.ncpu.
6586
mib := [2]uint32{_CTL_HW, _HW_NCPU}

src/runtime/sys_darwin_amd64.s

+50-52
Original file line numberDiff line numberDiff line change
@@ -122,36 +122,34 @@ TEXT runtime·madvise(SB), NOSPLIT, $0
122122
// OS X comm page time offsets
123123
// https://opensource.apple.com/source/xnu/xnu-4570.1.46/osfmk/i386/cpu_capabilities.h
124124

125-
#define commpage_version 0x1e
126-
127-
#define v12_nt_tsc_base 0x50
128-
#define v12_nt_scale 0x58
129-
#define v12_nt_shift 0x5c
130-
#define v12_nt_ns_base 0x60
131-
#define v12_nt_generation 0x68
132-
#define v12_gtod_generation 0x6c // obsolete since High Sierra (v13)
133-
#define v12_gtod_ns_base 0x70 // obsolete since High Sierra (v13)
134-
#define v12_gtod_sec_base 0x78 // obsolete since High Sierra (v13)
135-
136-
#define v13_gtod_ns_base 0xd0
137-
#define v13_gtod_sec_ofs 0xd8
138-
#define v13_gtod_frac_ofs 0xe0
139-
#define v13_gtod_scale 0xe8
140-
#define v13_gtod_tkspersec 0xf0
125+
#define nt_tsc_base 0x50
126+
#define nt_scale 0x58
127+
#define nt_shift 0x5c
128+
#define nt_ns_base 0x60
129+
#define nt_generation 0x68
130+
#define gtod_generation 0x6c // obsolete since Darwin v17 (High Sierra)
131+
#define gtod_ns_base 0x70 // obsolete since Darwin v17 (High Sierra)
132+
#define gtod_sec_base 0x78 // obsolete since Darwin v17 (High Sierra)
133+
134+
#define v17_gtod_ns_base 0xd0
135+
#define v17_gtod_sec_ofs 0xd8
136+
#define v17_gtod_frac_ofs 0xe0
137+
#define v17_gtod_scale 0xe8
138+
#define v17_gtod_tkspersec 0xf0
141139

142140
TEXT runtime·nanotime(SB),NOSPLIT,$0-8
143141
MOVQ $0x7fffffe00000, BP /* comm page base */
144142
// Loop trying to take a consistent snapshot
145143
// of the time parameters.
146144
timeloop:
147-
MOVL v12_nt_generation(BP), R9
145+
MOVL nt_generation(BP), R9
148146
TESTL R9, R9
149147
JZ timeloop
150148
RDTSC
151-
MOVQ v12_nt_tsc_base(BP), R10
152-
MOVL v12_nt_scale(BP), R11
153-
MOVQ v12_nt_ns_base(BP), R12
154-
CMPL v12_nt_generation(BP), R9
149+
MOVQ nt_tsc_base(BP), R10
150+
MOVL nt_scale(BP), R11
151+
MOVQ nt_ns_base(BP), R12
152+
CMPL nt_generation(BP), R9
155153
JNE timeloop
156154

157155
// Gathered all the data we need. Compute monotonic time:
@@ -173,32 +171,32 @@ TEXT time·now(SB), NOSPLIT, $32-24
173171
// are used in the systime fallback, as the timeval address
174172
// filled in by the system call.
175173
MOVQ $0x7fffffe00000, BP /* comm page base */
176-
CMPW commpage_version(BP), $13
177-
JB v12 /* sierra and older */
174+
CMPQ runtime·darwinVersion(SB), $17
175+
JB legacy /* sierra and older */
178176

179-
// This is the new code, for macOS High Sierra (v13) and newer.
180-
v13:
177+
// This is the new code, for macOS High Sierra (Darwin v17) and newer.
178+
v17:
181179
// Loop trying to take a consistent snapshot
182180
// of the time parameters.
183-
timeloop13:
184-
MOVQ v13_gtod_ns_base(BP), R12
181+
timeloop17:
182+
MOVQ v17_gtod_ns_base(BP), R12
185183

186-
MOVL v12_nt_generation(BP), CX
184+
MOVL nt_generation(BP), CX
187185
TESTL CX, CX
188-
JZ timeloop13
186+
JZ timeloop17
189187
RDTSC
190-
MOVQ v12_nt_tsc_base(BP), SI
191-
MOVL v12_nt_scale(BP), DI
192-
MOVQ v12_nt_ns_base(BP), BX
193-
CMPL v12_nt_generation(BP), CX
194-
JNE timeloop13
195-
196-
MOVQ v13_gtod_sec_ofs(BP), R8
197-
MOVQ v13_gtod_frac_ofs(BP), R9
198-
MOVQ v13_gtod_scale(BP), R10
199-
MOVQ v13_gtod_tkspersec(BP), R11
200-
CMPQ v13_gtod_ns_base(BP), R12
201-
JNE timeloop13
188+
MOVQ nt_tsc_base(BP), SI
189+
MOVL nt_scale(BP), DI
190+
MOVQ nt_ns_base(BP), BX
191+
CMPL nt_generation(BP), CX
192+
JNE timeloop17
193+
194+
MOVQ v17_gtod_sec_ofs(BP), R8
195+
MOVQ v17_gtod_frac_ofs(BP), R9
196+
MOVQ v17_gtod_scale(BP), R10
197+
MOVQ v17_gtod_tkspersec(BP), R11
198+
CMPQ v17_gtod_ns_base(BP), R12
199+
JNE timeloop17
202200

203201
// Compute monotonic time
204202
// mono = ((tsc - nt_tsc_base) * nt_scale) >> 32 + nt_ns_base
@@ -240,24 +238,24 @@ timeloop13:
240238
MOVQ DX, nsec+8(FP)
241239
RET
242240

243-
// This is the legacy code needed for macOS Sierra (v12) and older.
244-
v12:
241+
// This is the legacy code needed for macOS Sierra (Darwin v16) and older.
242+
legacy:
245243
// Loop trying to take a consistent snapshot
246244
// of the time parameters.
247245
timeloop:
248-
MOVL v12_gtod_generation(BP), R8
249-
MOVL v12_nt_generation(BP), R9
246+
MOVL gtod_generation(BP), R8
247+
MOVL nt_generation(BP), R9
250248
TESTL R9, R9
251249
JZ timeloop
252250
RDTSC
253-
MOVQ v12_nt_tsc_base(BP), R10
254-
MOVL v12_nt_scale(BP), R11
255-
MOVQ v12_nt_ns_base(BP), R12
256-
CMPL v12_nt_generation(BP), R9
251+
MOVQ nt_tsc_base(BP), R10
252+
MOVL nt_scale(BP), R11
253+
MOVQ nt_ns_base(BP), R12
254+
CMPL nt_generation(BP), R9
257255
JNE timeloop
258-
MOVQ v12_gtod_ns_base(BP), R13
259-
MOVQ v12_gtod_sec_base(BP), R14
260-
CMPL v12_gtod_generation(BP), R8
256+
MOVQ gtod_ns_base(BP), R13
257+
MOVQ gtod_sec_base(BP), R14
258+
CMPL gtod_generation(BP), R8
261259
JNE timeloop
262260

263261
// Gathered all the data we need. Compute:

0 commit comments

Comments
 (0)