diff options
author | 2022-04-04 15:23:43 +0100 | |
---|---|---|
committer | 2022-04-05 15:21:53 +0000 | |
commit | b567880e8c53641c519f601808191097e73dc4cd (patch) | |
tree | 08b4c540b4eb9ac41b0f9af327f41eb4f735b454 | |
parent | 62df93ba56737f761cff0c40aa68a20626decfb6 (diff) |
Implement JVM_GetNanoTimeAdjustment
Bug: 180577079
Test: atest CtsLibcoreOjTestCases:test.java.time.TestClock_System
Change-Id: I5300da80b5f8555358d0ab56a9340cebae765bab
-rw-r--r-- | openjdkjvm/OpenjdkJvm.cc | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/openjdkjvm/OpenjdkJvm.cc b/openjdkjvm/OpenjdkJvm.cc index 63503f459e..8c1f773ea3 100644 --- a/openjdkjvm/OpenjdkJvm.cc +++ b/openjdkjvm/OpenjdkJvm.cc @@ -210,6 +210,33 @@ JNIEXPORT jlong JVM_CurrentTimeMillis(JNIEnv* env ATTRIBUTE_UNUSED, return when; } +/** + * See the spec of this function in jdk.internal.misc.VM. + * @return -1 if the system time isn't within +/- 2^32 seconds from offset_secs + */ +JNIEXPORT jlong JVM_GetNanoTimeAdjustment(JNIEnv *ATTRIBUTE_UNUSED, + jclass ATTRIBUTE_UNUSED, + jlong offset_secs) { + struct timeval tv; + // Note that we don't want the elapsed time here, but the system clock. + // gettimeofday() doesn't provide nanosecond-level precision. + // clock_gettime(CLOCK_REALTIME, tp) may provide nanosecond-level precision. + // If it does support higher precision, we should switch both + // JVM_CurrentTimeMillis and JVM_GetNanoTimeAdjustment to use clock_gettime + // instead of gettimeofday() because various callers assume that + // System.currentTimeMillis() and VM.getNanoTimeAdjustment(offset) use the + // same time source. + gettimeofday(&tv, (struct timezone *) nullptr); + jlong sec_diff = ((jlong) tv.tv_sec) - offset_secs; + const jlong max_diff = ((jlong) 1) << 32; + const jlong min_diff = -max_diff; + if (sec_diff >= max_diff || sec_diff <= min_diff) { + return -1; + } + jlong usec_diff = sec_diff * 1000000LL + tv.tv_usec; + return usec_diff * 1000; +} + JNIEXPORT jint JVM_Socket(jint domain, jint type, jint protocol) { return TEMP_FAILURE_RETRY(socket(domain, type, protocol)); } |