Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: use mach_absolute_time for runtime.nanotime #17610

Closed
quentinmit opened this issue Oct 26, 2016 · 10 comments

Comments

Projects
None yet
7 participants
@quentinmit
Copy link
Contributor

commented Oct 26, 2016

runtime.nanotime currently returns wallclock time, which means timers do not function correctly in the presence of NTP. We should use mach_absolute_time instead, which returns a monotonic nanoseconds-since-boot timer. (Officially, it returns time in "absolute time units" and you have to multiply by a constant to get nanoseconds. But the implementation of both mach_absolute_time and gettimeofday assume/document that it's really nanoseconds...)

This has the bonus of being much simpler than gettimeofday, so it will also reduce our chances of being hit by a change in the kernel ABI.

Targeting 1.9 because this seems too dangerous for 1.8.

@quentinmit quentinmit added this to the Go1.9Early milestone Oct 26, 2016

@aclements

This comment has been minimized.

Copy link
Member

commented Oct 31, 2016

I flipped through the other OSs. A few others use wall-clock time, as well:

  • Solaris uses clock_gettime(CLOCK_REALTIME). If the internet rumors are true, Solaris doesn't have CLOCK_MONOTONIC. We should perhaps use gethrtime on Solaris.
  • NetBSD uses clock_gettime(CLOCK_REALTIME). As far as I can tell, CLOCK_MONOTONIC is available and we should use it.
  • NaCl and Plan9, but there's probably nothing we can do about these.
@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

commented Oct 31, 2016

At least Solaris version 12 does have CLOCK_MONOTONIC. It is documented as CLOCK_HIGHRES, but CLOCK_MONOTONIC is defined in <time.h> to the same value as CLOCK_HIGHRES and CLOCK_HIGHRES is defined by the man page to be monotonic.

@namsral

This comment has been minimized.

Copy link
Contributor

commented Jan 11, 2017

FYI clock_gettime was introduced in September 2016 with the release of macOS 10.12 (Sierra)

@minux

This comment has been minimized.

Copy link
Member

commented Jan 11, 2017

@bradfitz

This comment has been minimized.

Copy link
Member

commented Jan 11, 2017

@minux, we can use it when available.

@minux

This comment has been minimized.

Copy link
Member

commented Jan 11, 2017

@namsral

This comment has been minimized.

Copy link
Contributor

commented Jan 12, 2017

Using mach_timebase_info you can convert Mach absolute time to nanoseconds:

mach_timebase_info_data_t info;
mach_timebase_info(&info);

uint64_t start = mach_absolute_time();
usleep(2000000);
uint64_t duration = mach_absolute_time() - start;

// Convert to nanoseconds
duration = duration * info.numer / info.denom;

printf("%lld ns\n", (long long) duration);

From developer.apple.com

@minux

This comment has been minimized.

Copy link
Member

commented Jan 12, 2017

@namsral

This comment has been minimized.

Copy link
Contributor

commented Jan 16, 2017

My nanotime replacement to support monototic nanoseconds:

TEXT runtime·nanotime(SB), NOSPLIT, $32
	MOVQ $0x7fffffe00000, SI // comm page base

timeloop:
	MOVL  nt_generation(SI), R8
	TESTL R8, R8
	JZ    timeloop
	RDTSC
	SHLQ  $32, DX
	ORQ   DX, AX
	MOVL nt_shift(SI), CX
	SUBQ nt_tsc_base(SI), AX
	SHLQ CX, AX
	MOVL nt_scale(SI), CX
	MULQ CX
	SHRQ $32, AX:DX
	ADDQ nt_ns_base(SI), AX
	CMPL nt_generation(SI), R8
	JNE  timeloop
	MOVQ AX, ret+0(FP)
	RET

The algorithm is based on xnu's mach_absolute_time and works on Intel Macs.

My intention is to follow Go's contributions guidelines next.

@gopherbot

This comment has been minimized.

Copy link

commented Jan 17, 2017

CL https://golang.org/cl/35292 mentions this issue.

@gopherbot gopherbot closed this in e546b29 Feb 2, 2017

@golang golang locked and limited conversation to collaborators Feb 2, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.