[cp-patches] [PATCH] native: Use CLOCK_MONOTONIC for System.nanoTime

Pekka Enberg penberg at kernel.org
Thu Sep 23 16:20:40 UTC 2010


From: Roland Brand <roland.brand at 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: AdamB <adamb at videx.com>
Cc: Mark Wielaard <mark at klomp.org>
Cc: Roland Brand <roland.brand at ergon.ch>
Bugzilla-URL: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44411
Signed-off-by: Pekka Enberg <penberg at kernel.org>
---
 native/jni/java-lang/java_lang_VMSystem.c |   26 +++++++++++++++++++++++++-
 vm/reference/java/lang/VMSystem.java      |    5 +----
 2 files changed, 26 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..80315a5 100644
--- a/native/jni/java-lang/java_lang_VMSystem.c
+++ b/native/jni/java-lang/java_lang_VMSystem.c
@@ -39,6 +39,7 @@ exception statement from your version. */
 
 #include <jcl.h>
 
+#include <time.h>
 #include <sys/time.h>
 #include <stdlib.h>
 
@@ -121,6 +122,29 @@ 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)
+    (*env)->FatalError (env, "clock_gettime call failed.");
+
+  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 +155,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




More information about the Classpath-patches mailing list