JDK-8040140 : System.nanoTime() is slow and non-monotonic on OS X
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 7u80,9
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: os_x
  • Submitted: 2014-04-14
  • Updated: 2014-07-29
  • Resolved: 2014-04-25
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u20Fixed 9 b13Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
The current implementation of System.nanoTime() on OS X uses gettimeofday() which has only microsecond precision and no guarantees on being monotonic.
Comments
Results from the org.openjdk.jmh.benchmarks.NanoTimerBench (http://hg.openjdk.java.net/code-tools/jmh/file/57623b7f64e6/jmh-core-benchmarks/src/main/java/org/openjdk/jmh/benchmarks/NanoTimerBench.java) JMH benchmark: gettimeofday() one thread (-wi 1 -f 0 -t 1) Benchmark Mode Samples Mean Mean error Units o.o.j.b.NanoTimerBench.granularity avgt 5 1045.209 14.944 ns/op o.o.j.b.NanoTimerBench.latency avgt 5 48.219 1.234 ns/op mach_absolute_time() with monotonic guarantee, one thread (-wi 1 -f 0 -t 1) Benchmark Mode Samples Mean Mean error Units o.o.j.b.NanoTimerBench.granularity avgt 5 41.527 3.871 ns/op o.o.j.b.NanoTimerBench.latency avgt 5 40.995 2.578 ns/op gettimeofday() five threads (-wi 1 -f 0 -t 5) Benchmark Mode Samples Mean Mean error Units o.o.j.b.NanoTimerBench.latency avgt 5 76.166 20.690 ns/op mach_absolute_time() with monotonic guarantee, five threads (-wi 1 -f 0 -t 5) Benchmark Mode Samples Mean Mean error Units o.o.j.b.NanoTimerBench.latency avgt 5 156.376 21.081 ns/op
14-04-2014

The proposal is to use the system call mach_absolute_time() instead of gettimeofday() and to add safeguard to guarantee that the time is monotonic (similar to what we already have on solaris). mach_absolute_time() is essentially a direct call to RDTSC, but with conversion factor to offset for any system sleeps and frequency changes. The call returns something that can be converted to nanoseconds using information from mach_timebase_info(). Calls to mach_absolute_time() do not enter the kernel and are very fast. The resulting time has nanosecond precision and as good accuracy as one can get. Since the value from RDTSC can be subject to drifting between CPUs, we implement safeguards for this to make sure we never return a lower value than the previous values. This adds some overhead to nanoTime() but guards us against possible bugs in the OS. For users who are willing to trust the OS and need the fastest possible calls to System.nanoTime(), we add a flag to disable this safeguard: -XX:+AssumeMonotonicOSTimers (see JDK-6864866).
14-04-2014