Bug 44411

Summary: System.nanoTime() is not independent of wall-clock time
Product: classpath Reporter: AdamB <adamb>
Component: classpathAssignee: Andrew John Hughes <gnu_andrew>
Status: RESOLVED FIXED    
Severity: normal CC: bug-classpath, gnu_andrew, roland.brand
Priority: P3    
Version: 0.98   
Target Milestone: 0.99   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:
Attachments: Patch for System.nanoTime

Description AdamB 2010-06-04 00:12:14 UTC
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.  Perhaps the clock_gettime function would work (http://www.tin.org/bin/man.cgi?section=3&topic=clock_gettime) or the getrusage function.
Comment 1 Roland Brand 2010-07-08 11:55:07 UTC
Created attachment 21141 [details]
Patch for System.nanoTime

I use classpath in a productive environment and I depend on a wall-clock-independent implementation of System.nanoTime(). So I created a patch using clock_gettime() instead of gettimeofday().
Comment 2 AdamB 2010-07-09 00:25:14 UTC
Looks like a good patch, Roland.  Hopefully they will incorporate it into the official code.

The only thing I'd add is some #ifdef logic so that old Linux versions without CLOCK_MONOTONIC support will fallback to the existing gettimeofday implementation.
Comment 3 Andrew John Hughes 2010-11-05 00:18:31 UTC
CVSROOT:        /sources/classpath
Module name:    classpath
Changes by:     Andrew John Hughes <gnu_andrew> 10/11/05 00:09:47

Modified files:
       .              : ChangeLog
       native/jni/java-lang: java_lang_VMSystem.c
       vm/reference/java/lang: VMSystem.java

Log message:
       PR44411: Make VMSystem.nanoTime independent of wall time where possible.

       2010-11-04  Andrew John Hughes  <ahughes@redhat.com>

               Provide a fallback for systems without POSIX timers.
               * native/jni/java-lang/java_lang_VMSystem.c:
               (currentTimeMillis): New function which provides
               the behaviour for both Java_java_lang_VMSystem_currentTimeMillis
               and the fallback by obtaining the result of gettimeofday.
               (Java_java_lang_VMSystem_nanoTime): Return currentTimeMillis
               multiplied by a 1000 if a monotonic clock is unavailable.
               (Java_java_lang_VMSystem_currentTimeMillis): Split main behaviour
               out into currentTimeMillis and then return its result divided by a
               1000.

       2010-07-08  Roland Brand  <roland.brand@ergon.ch>
               Pekka Enberg  <penberg@kernel.org>

               PR classpath/44411
               * native/jni/java-lang/java_lang_VMSystem.c:
               (Java_java_lang_VMSystem_nanoTime): Implement
               using POSIX monotonic clock support and clock_gettime.
               (Java_java_lang_VMSystem_currentTimeMillis):
               Use old nanoTime method (which uses gettimeofday) to
               provide the current time in milliseconds.
               * vm/reference/java/lang/VMSystem.java:
               (currentTimeMillis()): Make native with its own implementation
               rather than using nanoTime, which should be
               independent of wall-clock time.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/classpath/ChangeLog?cvsroot=classpath&r1=1.9802&r2=1.9803
http://cvs.savannah.gnu.org/viewcvs/classpath/native/jni/java-lang/java_lang_VMSystem.c?cvsroot=classpath&r1=1.15&r2=1.16
http://cvs.savannah.gnu.org/viewcvs/classpath/vm/reference/java/lang/VMSystem.java?cvsroot=classpath&r1=1.19&r2=1.20
Comment 4 Andrew John Hughes 2010-11-05 00:19:07 UTC
Set target to 0.99