diff options
Diffstat (limited to 'openjdkjvm/OpenjdkJvm.cc')
-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)); } |