MOVL g(CX), DI
CMPL SI, DI
JEQ noswitch
+ CMPL DI, m_gsignal(BP)
+ JEQ noswitch
CALL gosave<>(SB)
get_tls(CX)
MOVL SI, g(CX)
#define __DARWIN_UNIX03 0
#include <mach/mach.h>
#include <mach/message.h>
+#include <mach/mach_time.h>
#include <sys/types.h>
#include <sys/time.h>
#include <errno.h>
type Pthread C.pthread_t
type PthreadAttr C.pthread_attr_t
+
+type MachTimebaseInfo C.mach_timebase_info_data_t
X__sig int32
X__opaque [36]int8
}
+type machTimebaseInfo struct {
+ numer uint32
+ denom uint32
+}
X__sig int64
X__opaque [56]int8
}
+type machTimebaseInfo struct {
+ numer uint32
+ denom uint32
+}
// +build !windows
// +build !nacl
// +build !freebsd
+// +build !darwin
package runtime
--- /dev/null
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin,arm darwin,arm64
+
+package runtime
+
+func nanotime() int64
}
func open_trampoline()
+//go:nosplit
+//go:cgo_unsafe_args
+func nanotime() int64 {
+ var r struct {
+ t int64 // raw timer
+ numer, denom uint32 // conversion factors. nanoseconds = t * numer / denom.
+ }
+ asmcgocall(unsafe.Pointer(funcPC(nanotime_trampoline)), unsafe.Pointer(&r))
+ // Note: Apple seems unconcerned about overflow here. See
+ // https://developer.apple.com/library/content/qa/qa1398/_index.html
+ // Note also, numer == denom == 1 is common.
+ t := r.t
+ if r.numer != 1 {
+ t *= int64(r.numer)
+ }
+ if r.denom != 1 {
+ t /= int64(r.denom)
+ }
+ return t
+}
+func nanotime_trampoline()
+
// Not used on Darwin, but must be defined.
func exitThread(wait *uint32) {
}
//go:cgo_import_dynamic libc_error __error "/usr/lib/libSystem.B.dylib"
//go:cgo_import_dynamic libc_usleep usleep "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_mach_timebase_info mach_timebase_info "/usr/lib/libSystem.B.dylib"
+//go:cgo_import_dynamic libc_mach_absolute_time mach_absolute_time "/usr/lib/libSystem.B.dylib"
+
// Magic incantation to get libSystem actually dynamically linked.
// TODO: Why does the code require this? See cmd/compile/internal/ld/go.go:210
//go:cgo_import_dynamic _ _ "/usr/lib/libSystem.B.dylib"
MOVL DX, nsec+8(FP)
RET
-// func nanotime() int64
-TEXT runtime·nanotime(SB),NOSPLIT,$0
- CALL runtime·now(SB)
- SUBL runtime·startNano(SB), AX
- SBBL runtime·startNano+4(SB), DX
- MOVL AX, ret_lo+0(FP)
- MOVL DX, ret_hi+4(FP)
+GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
+
+TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0
+ PUSHL BP
+ MOVL SP, BP
+ SUBL $8+(machTimebaseInfo__size+15)/16*16, SP
+ CALL libc_mach_absolute_time(SB)
+ MOVL 16+(machTimebaseInfo__size+15)/16*16(SP), CX
+ MOVL AX, 0(CX)
+ MOVL DX, 4(CX)
+ MOVL timebase<>+machTimebaseInfo_denom(SB), DI // atomic read
+ MOVL timebase<>+machTimebaseInfo_numer(SB), SI
+ TESTL DI, DI
+ JNE initialized
+
+ LEAL 4(SP), AX
+ MOVL AX, 0(SP)
+ CALL libc_mach_timebase_info(SB)
+ MOVL 4+machTimebaseInfo_numer(SP), SI
+ MOVL 4+machTimebaseInfo_denom(SP), DI
+
+ MOVL SI, timebase<>+machTimebaseInfo_numer(SB)
+ MOVL DI, AX
+ XCHGL AX, timebase<>+machTimebaseInfo_denom(SB) // atomic write
+ MOVL 16+(machTimebaseInfo__size+15)/16*16(SP), CX
+
+initialized:
+ MOVL SI, 8(CX)
+ MOVL DI, 12(CX)
+ MOVL BP, SP
+ POPL BP
RET
TEXT runtime·sigprocmask(SB),NOSPLIT,$0
#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 nt_generation(BP), R9
- TESTL R9, R9
- JZ timeloop
- RDTSC
- MOVQ nt_tsc_base(BP), R10
- MOVL nt_scale(BP), R11
- MOVQ nt_ns_base(BP), R12
- CMPL nt_generation(BP), R9
- JNE timeloop
+GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size)
- // Gathered all the data we need. Compute monotonic time:
- // ((tsc - nt_tsc_base) * nt_scale) >> 32 + nt_ns_base
- // The multiply and shift extracts the top 64 bits of the 96-bit product.
- SHLQ $32, DX
- ADDQ DX, AX
- SUBQ R10, AX
- MULQ R11
- SHRQ $32, AX:DX
- ADDQ R12, AX
- MOVQ runtime·startNano(SB), CX
- SUBQ CX, AX
- MOVQ AX, ret+0(FP)
+TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0
+ PUSHQ BP
+ MOVQ SP, BP
+ MOVQ DI, BX
+ CALL libc_mach_absolute_time(SB)
+ MOVQ AX, 0(BX)
+ MOVL timebase<>+machTimebaseInfo_numer(SB), SI
+ MOVL timebase<>+machTimebaseInfo_denom(SB), DI // atomic read
+ TESTL DI, DI
+ JNE initialized
+
+ SUBQ $(machTimebaseInfo__size+15)/16*16, SP
+ MOVQ SP, DI
+ CALL libc_mach_timebase_info(SB)
+ MOVL machTimebaseInfo_numer(SP), SI
+ MOVL machTimebaseInfo_denom(SP), DI
+ ADDQ $(machTimebaseInfo__size+15)/16*16, SP
+
+ MOVL SI, timebase<>+machTimebaseInfo_numer(SB)
+ MOVL DI, AX
+ XCHGL AX, timebase<>+machTimebaseInfo_denom(SB) // atomic write
+
+initialized:
+ MOVL SI, 8(BX)
+ MOVL DI, 12(BX)
+ MOVQ BP, SP
+ POPQ BP
RET
TEXT time·now(SB), NOSPLIT, $32-24