From: Roland Brand <roland.br...@ergon.ch>

As explained by AdamB:

  On Linux, Classpath appears to implement the System.nanoTime() function using
  the gettimeofday function (see java_lang_VMSystem.c).  Since gettimeofday
  returns a wall-clock time this makes it unreliable for measuring elapsed time,
  (because the system clock could be changed by another process at any moment.

  According to the Sun javadocs:

      ... This method can only be used to measure elapsed time and is not
      related to any other notion of system or wall-clock time. The
      value returned represents nanoseconds since some fixed but
      arbitrary time ...

  In short, gettimeofday is not appropriate for measuring elapsed time.

This patch fixes System.nanoTime() to use CLOCK_MONOTONIC which is what OpenJDK
does as well.

Cc: Andrew Hughes <gnu_and...@members.fsf.org>
Cc: AdamB <ad...@videx.com>
Cc: Mark Wielaard <m...@klomp.org>
Cc: Roland Brand <roland.br...@ergon.ch>
Bugzilla-URL: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44411
Signed-off-by: Pekka Enberg <penb...@kernel.org>
---
v1 -> v2: Use strerror() to pass human readable error message to FatalError()
          as suggested by Andrew Hughes

 native/jni/java-lang/java_lang_VMSystem.c |   30 ++++++++++++++++++++++++++++-
 vm/reference/java/lang/VMSystem.java      |    5 +---
 2 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/native/jni/java-lang/java_lang_VMSystem.c 
b/native/jni/java-lang/java_lang_VMSystem.c
index d203227..4ff7355 100644
--- a/native/jni/java-lang/java_lang_VMSystem.c
+++ b/native/jni/java-lang/java_lang_VMSystem.c
@@ -39,8 +39,10 @@ exception statement from your version. */
 
 #include <jcl.h>
 
+#include <time.h>
 #include <sys/time.h>
 #include <stdlib.h>
+#include <errno.h>
 
 /*
  * Class:     java_lang_VMSystem
@@ -121,6 +123,32 @@ Java_java_lang_VMSystem_nanoTime
   (JNIEnv * env __attribute__ ((__unused__)),
    jclass thisClass __attribute__ ((__unused__)))
 {
+  jlong result;
+  struct timespec tp;
+
+  if (clock_gettime (CLOCK_MONOTONIC, &tp) == -1) {
+    char error[64];
+    snprintf(error, 64, "clock_gettime call failed: %s.", strerror(errno));
+    (*env)->FatalError (env, error);
+  }
+
+  result = (jlong) tp.tv_sec;
+  result *= (jlong)1000000000L;
+  result += (jlong)tp.tv_nsec;
+
+  return result;
+}
+
+/*
+ * Class:     java_lang_VMSystem
+ * Method:    currentTimeMillis
+ * Signature: ()J
+ */
+JNIEXPORT jlong JNICALL
+Java_java_lang_VMSystem_currentTimeMillis
+  (JNIEnv * env __attribute__ ((__unused__)),
+   jclass thisClass __attribute__ ((__unused__)))
+{
   /* Note: this implementation copied directly from Japhar's, by Chris Toshok. 
*/
   jlong result;
   struct timeval tp;
@@ -131,7 +159,7 @@ Java_java_lang_VMSystem_nanoTime
   result = (jlong) tp.tv_sec;
   result *= (jlong)1000000L;
   result += (jlong)tp.tv_usec;
-  result *= (jlong)1000;
+  result /= (jlong)1000L;
 
   return result;
 }
diff --git a/vm/reference/java/lang/VMSystem.java 
b/vm/reference/java/lang/VMSystem.java
index a194663..0b3d692 100644
--- a/vm/reference/java/lang/VMSystem.java
+++ b/vm/reference/java/lang/VMSystem.java
@@ -129,10 +129,7 @@ final class VMSystem
    * @return the current time
    * @see java.util.Date
    */
-   static long currentTimeMillis()
-   {
-     return nanoTime() / 1000000L;
-   }
+  static native long currentTimeMillis();
 
   /**
    * <p>
-- 
1.7.0.4


Reply via email to