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: 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> --- 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