From: Roland Brand <[email protected]>
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 <[email protected]>
Cc: Mark Wielaard <[email protected]>
Cc: Roland Brand <[email protected]>
Bugzilla-URL: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44411
Signed-off-by: Pekka Enberg <[email protected]>
---
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