Implement JVM_GetNanoTimeAdjustment

Bug: 180577079
Test: atest CtsLibcoreOjTestCases:test.java.time.TestClock_System
Change-Id: I5300da80b5f8555358d0ab56a9340cebae765bab
diff --git a/openjdkjvm/OpenjdkJvm.cc b/openjdkjvm/OpenjdkJvm.cc
index 63503f4..8c1f773 100644
--- a/openjdkjvm/OpenjdkJvm.cc
+++ b/openjdkjvm/OpenjdkJvm.cc
@@ -210,6 +210,33 @@
     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));
 }