diff --git a/tstime/monocoarse_asm.go b/tstime/monocoarse_asm.go index 0c88c1d73..32c29fd4f 100644 --- a/tstime/monocoarse_asm.go +++ b/tstime/monocoarse_asm.go @@ -3,9 +3,32 @@ package tstime +const ( + CLOCK_MONOTONIC = 1 + CLOCK_MONOTONIC_COARSE = 6 +) + // MonotonicCoarse returns the number of monotonic seconds elapsed // since an unspecified starting point, at low precision. // It is only meaningful when compared to the // result of previous MonotonicCoarse calls. // On some platforms, MonotonicCoarse is much faster than time.Now. -func MonotonicCoarse() int64 +func monoClock(clock int) int64 + +// Monotonic returns the number of monotonic seconds elapsed +// since an unspecified starting point, at low precision. +// It is only meaningful when compared to the +// result of previous Monotonic calls. +// On some platforms, Monotonic is much faster than time.Now. +func Monotonic() int64 { + return monoClock(CLOCK_MONOTONIC) +} + +// MonotonicCoarse returns the number of monotonic seconds elapsed +// since an unspecified starting point, at low precision. +// It is only meaningful when compared to the +// result of previous MonotonicCoarse calls. +// On some platforms, MonotonicCoarse is much faster than time.Now. +func MonotonicCoarse() int64 { + return monoClock(CLOCK_MONOTONIC_COARSE) +} diff --git a/tstime/monocoarse_linux_amd64.s b/tstime/monocoarse_linux_amd64.s index 7e1801570..cb96e85fd 100644 --- a/tstime/monocoarse_linux_amd64.s +++ b/tstime/monocoarse_linux_amd64.s @@ -42,10 +42,10 @@ #define m_vdsoSP 832 #define m_vdsoPC 840 -#define CLOCK_MONOTONIC 1 +// func monoClock(clock int) int64 +TEXT ·monoClock(SB),NOSPLIT,$16-16 + MOVQ clock+0(FP), DI -// func MonotonicCoarse() int64 -TEXT ·MonotonicCoarse(SB),NOSPLIT,$16-8 // Switch to g0 stack. MOVQ SP, R12 // Save old SP; R12 unchanged by C code. @@ -62,7 +62,7 @@ TEXT ·MonotonicCoarse(SB),NOSPLIT,$16-8 MOVQ CX, 0(SP) MOVQ DX, 8(SP) - LEAQ ret+0(FP), DX + LEAQ ret+8(FP), DX MOVQ -8(DX), CX MOVQ CX, m_vdsoPC(BX) MOVQ DX, m_vdsoSP(BX) @@ -77,7 +77,6 @@ noswitch: SUBQ $16, SP // Space for results ANDQ $~15, SP // Align for C code - MOVL $CLOCK_MONOTONIC, DI LEAQ 0(SP), SI MOVQ runtime·vdsoClockgettimeSym(SB), AX CMPQ AX, $0 @@ -100,7 +99,7 @@ ret: // return nsec in AX IMULQ $1000000000, AX ADDQ DX, AX - MOVQ AX, ret+0(FP) + MOVQ AX, ret+8(FP) RET fallback: MOVQ $SYS_clock_gettime, AX diff --git a/tstime/monocoarse_linux_arm64.s b/tstime/monocoarse_linux_arm64.s index b13e1c051..f92694f2a 100644 --- a/tstime/monocoarse_linux_arm64.s +++ b/tstime/monocoarse_linux_arm64.s @@ -45,10 +45,11 @@ #define m_vdsoPC 840 #define m_gsignal 80 -#define CLOCK_MONOTONIC 1 -// func MonotonicCoarse() int64 -TEXT ·MonotonicCoarse(SB),NOSPLIT,$24-8 +// func monoClock(clock int) int64 +TEXT ·monoClock(SB),NOSPLIT,$24-16 + MOVD clock+0(FP), R22 + MOVD RSP, R20 // R20 is unchanged by C code MOVD RSP, R1 @@ -77,7 +78,7 @@ noswitch: BIC $15, R1 MOVD R1, RSP - MOVW $CLOCK_MONOTONIC, R0 + MOVW R22, R0 MOVD runtime·vdsoClockgettimeSym(SB), R2 CBZ R2, fallback @@ -132,5 +133,5 @@ finish: MOVD $1000000000, R4 MUL R4, R3 ADD R5, R3 - MOVD R3, ret+0(FP) + MOVD R3, ret+8(FP) RET diff --git a/tstime/monocoarse_std.go b/tstime/monocoarse_std.go index 8a289dcee..24630e167 100644 --- a/tstime/monocoarse_std.go +++ b/tstime/monocoarse_std.go @@ -14,3 +14,12 @@ func MonotonicCoarse() int64 { return int64(time.Since(referenceTime).Seconds()) } + +// Monotonic returns the number of monotonic seconds elapsed +// since an unspecified starting point, at low precision. +// It is only meaningful when compared to the +// result of previous MonotonicCoarse calls. +// On some platforms, MonotonicCoarse is much faster than time.Now. +func Monotonic() int64 { + return int64(time.Since(referenceTime).Seconds()) +} diff --git a/tstime/monocoarse_test.go b/tstime/monocoarse_test.go index f2fdc0659..9a0e3ea18 100644 --- a/tstime/monocoarse_test.go +++ b/tstime/monocoarse_test.go @@ -22,6 +22,12 @@ func TestMonotonicCoarse(t *testing.T) { t.Errorf("monotonic coarse time did not progress after 3s") } +func BenchmarkMonotonic(b *testing.B) { + for i := 0; i < b.N; i++ { + Monotonic() + } +} + func BenchmarkMonotonicCoarse(b *testing.B) { for i := 0; i < b.N; i++ { MonotonicCoarse()