JDK-8242504 : Enhance the system clock to nanosecond precision
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 15
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2020-04-10
  • Updated: 2020-08-19
  • Resolved: 2020-05-29
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 15
15 b26Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Enhance the system clock to nanosecond precision.

Refer to the email for details: "os::javaTimeSystemUTC to call nanosecond precision OS API, so Clock.systemUTC() can give nanosecond precision UTC"

https://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2020-April/038975.html



Comments
URL: https://hg.openjdk.java.net/jdk/jdk/rev/f1f88e6fad02 User: dholmes Date: 2020-05-29 02:35:29 +0000
29-05-2020

A simple demo program: import java.time.*; public class ShowTime { static int SAMPLES = 20; public static void main(String[] args) throws Throwable { if (args.length > 0) { SAMPLES = Integer.parseInt(args[0]); } long[] milliSamples = new long[SAMPLES]; long[] instantSamples = new long[SAMPLES]; Clock c = Clock.systemUTC(); for (int i = 0; i < SAMPLES; i++) { Instant t = c.instant(); long millis = System.currentTimeMillis(); milliSamples[i] = millis * 1000 * 1000; long secs = t.getEpochSecond(); long nanos = t.getNano(); instantSamples[i] = secs * 1000 * 1000 * 1000 + nanos; } System.out.printf("%16s %16s%n", "currentTimeMilli", "systemUTC"); for (int i = 0; i < SAMPLES; i++) { System.out.printf("%16d %16d%n", milliSamples[i], instantSamples[i]); } } } Output before: currentTimeMilli systemUTC 1590402378946000000 1590402378946415000 1590402378946000000 1590402378946805000 1590402378946000000 1590402378946808000 1590402378946000000 1590402378946811000 1590402378946000000 1590402378946813000 1590402378946000000 1590402378946815000 1590402378946000000 1590402378946817000 1590402378946000000 1590402378946820000 1590402378946000000 1590402378946822000 1590402378946000000 1590402378946824000 1590402378946000000 1590402378946826000 1590402378946000000 1590402378946828000 1590402378946000000 1590402378946830000 1590402378946000000 1590402378946832000 1590402378946000000 1590402378946834000 1590402378946000000 1590402378946836000 1590402378946000000 1590402378946838000 1590402378946000000 1590402378946840000 1590402378946000000 1590402378946843000 1590402378946000000 1590402378946845000 Output after: currentTimeMilli systemUTC 1590402336642000000 1590402336641685002 1590402336642000000 1590402336642105135 1590402336642000000 1590402336642109595 1590402336642000000 1590402336642112290 1590402336642000000 1590402336642114744 1590402336642000000 1590402336642116929 1590402336642000000 1590402336642119413 1590402336642000000 1590402336642121758 1590402336642000000 1590402336642124092 1590402336642000000 1590402336642126286 1590402336642000000 1590402336642128380 1590402336642000000 1590402336642130494 1590402336642000000 1590402336642132718 1590402336642000000 1590402336642135113 1590402336642000000 1590402336642137167 1590402336642000000 1590402336642139130 1590402336642000000 1590402336642141174 1590402336642000000 1590402336642143038 1590402336642000000 1590402336642145332 1590402336642000000 1590402336642147506
25-05-2020

Also see JDK-8068730. You will see that the original assumption in the upgraded implementation of Clock::systemUTC brought by JDK-8068730 is that System::currentTimeMillis and VM::getNanoTimeAdjustment must be based on the same time source. This is partly because System::currentTimeMillis is used to compute the original offset (though that would also work if System::currentTimeMillis and VM::getNanoTimeAdjustment were only weakly related), and mostly because SytemClock::millis continue calling System::currentTimeMillis as a fastpath (since IIRC System::currentTimeMillis is intrinsified) - whereas SystemClock::instant uses VM::getNanoTimeAdjustment to get sub-millisecond (and potentially nanosecond if that were available) precision. This is only possible if both calls (SystemClock::millis and SystemClock::instant) are based on the same time source - which is the invariant that should be maintained. That said it would be disturbing if System::currentTimeMillis and SystemClock were based on different time sources which would allow them to drift away from each other.
14-04-2020

My recollection is we tried using a high-precision clock source for systemUTC() in the past but it didn't work because systemUTC() and currentTimeMillis() have to use the same time base, and currentTimeMillis() has to use gettimeofday(). I will dig up the details/history. Update: please see: https://bugs.openjdk.java.net/browse/JDK-8185891?focusedCommentId=14107380&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-14107380 It seems switching from gettimeofday to clock_gettime(CLOCK_REALTIME) may indeed be viable.
11-04-2020