diff options
author | geoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-09-14 01:17:31 +0000 |
---|---|---|
committer | geoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-09-14 01:17:31 +0000 |
commit | 0bb92388895783dad3b13b8deb9d182bbedc5408 (patch) | |
tree | a5280d81d511353d5613e3482a10f15f1a24c4c1 /libjava | |
parent | 09fa572c45232c54bebd4f301df52f0112828ce4 (diff) | |
download | gcc-0bb92388895783dad3b13b8deb9d182bbedc5408.tar.gz |
* posix.cc (_Jv_platform_nanotime): Return nanoseconds, not
microseconds; use gettimeofday when available.
* posix-threads.cc (_Jv_CondWait): Improve accuracy and range of
timeout calculation.
* testsuite/libjava.lang/Thread_Sleep_2.java: New.
* testsuite/libjava.lang/Thread_Sleep_2.out: New.
* testsuite/libjava.lang/Thread_Sleep_2.xfail: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@116941 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava')
-rw-r--r-- | libjava/ChangeLog | 10 | ||||
-rw-r--r-- | libjava/posix-threads.cc | 39 | ||||
-rw-r--r-- | libjava/posix.cc | 12 | ||||
-rw-r--r-- | libjava/testsuite/libjava.lang/Thread_Sleep_2.java | 34 | ||||
-rw-r--r-- | libjava/testsuite/libjava.lang/Thread_Sleep_2.out | 1 | ||||
-rw-r--r-- | libjava/testsuite/libjava.lang/Thread_Sleep_2.xfail | 1 |
6 files changed, 81 insertions, 16 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog index da8704f72dc..3c7ee13f195 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,13 @@ +2006-09-13 Geoffrey Keating <geoffk@apple.com> + + * posix.cc (_Jv_platform_nanotime): Return nanoseconds, not + microseconds; use gettimeofday when available. + * posix-threads.cc (_Jv_CondWait): Improve accuracy and range of + timeout calculation. + * testsuite/libjava.lang/Thread_Sleep_2.java: New. + * testsuite/libjava.lang/Thread_Sleep_2.out: New. + * testsuite/libjava.lang/Thread_Sleep_2.xfail: New. + 2006-09-12 Tom Tromey <tromey@redhat.com> PR java/29013: diff --git a/libjava/posix-threads.cc b/libjava/posix-threads.cc index 48501628ad0..41937db6c52 100644 --- a/libjava/posix-threads.cc +++ b/libjava/posix-threads.cc @@ -96,16 +96,29 @@ _Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, if (millis > 0 || nanos > 0) { // Calculate the abstime corresponding to the timeout. - // Everything is in milliseconds. - // - // We use `unsigned long long' rather than jlong because our - // caller may pass up to Long.MAX_VALUE millis. This would - // overflow the range of a jlong when added to the current time. - - unsigned long long startTime - = (unsigned long long)java::lang::System::currentTimeMillis(); - unsigned long long m = (unsigned long long)millis + startTime; - unsigned long long seconds = m / 1000; + unsigned long long seconds; + unsigned long usec; + + // For better accuracy, should use pthread_condattr_setclock + // and clock_gettime. +#ifdef HAVE_GETTIMEOFDAY + timeval tv; + gettimeofday (&tv, NULL); + usec = tv.tv_usec; + seconds = tv.tv_sec; +#else + unsigned long long startTime = java::lang::System::currentTimeMillis(); + seconds = startTime / 1000; + /* Assume we're about half-way through this millisecond. */ + usec = (startTime % 1000) * 1000 + 500; +#endif + /* These next two statements cannot overflow. */ + usec += nanos / 1000; + usec += (millis % 1000) * 1000; + /* These two statements could overflow only if tv.tv_sec was + insanely large. */ + seconds += millis / 1000; + seconds += usec / 1000000; ts.tv_sec = seconds; if (ts.tv_sec < 0 || (unsigned long long)ts.tv_sec != seconds) @@ -115,10 +128,8 @@ _Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, millis = nanos = 0; } else - { - m %= 1000; - ts.tv_nsec = m * 1000000 + (unsigned long long)nanos; - } + /* This next statement also cannot overflow. */ + ts.tv_nsec = (usec % 1000000) * 1000 + (nanos % 1000); } _Jv_Thread_t *current = _Jv_ThreadCurrentData (); diff --git a/libjava/posix.cc b/libjava/posix.cc index d191d8ea7a1..df798b88a2b 100644 --- a/libjava/posix.cc +++ b/libjava/posix.cc @@ -87,12 +87,20 @@ _Jv_platform_nanotime () if (clock_gettime (id, &now) == 0) { jlong result = (jlong) now.tv_sec; - result = result * 1000 * 1000 + now.tv_nsec; + result = result * 1000000000LL + now.tv_nsec; return result; } // clock_gettime failed, but we can fall through. #endif // HAVE_CLOCK_GETTIME - return _Jv_platform_gettimeofday () * 1000LL; +#if defined (HAVE_GETTIMEOFDAY) + { + timeval tv; + gettimeofday (&tv, NULL); + return (tv.tv_sec * 1000000000LL) + tv.tv_usec * 1000LL; + } +#else + return _Jv_platform_gettimeofday () * 1000000LL; +#endif } // Platform-specific VM initialization. diff --git a/libjava/testsuite/libjava.lang/Thread_Sleep_2.java b/libjava/testsuite/libjava.lang/Thread_Sleep_2.java new file mode 100644 index 00000000000..37c0d3bb665 --- /dev/null +++ b/libjava/testsuite/libjava.lang/Thread_Sleep_2.java @@ -0,0 +1,34 @@ +// Test that Thread.sleep() is accurate +// and that nanoTime actually measures in nanoseconds. + +public class Thread_Sleep_2 +{ + public static void main(String args[]) + { + try + { + boolean ok = true; + for (int i = 0; i < 100; i++) + { + long start = System.nanoTime(); + Thread.sleep(10); + long end = System.nanoTime(); + if ((end - start) < 10000000) + { + System.out.print ("failed, iteration "); + System.out.print (i); + System.out.print (", time "); + System.out.print (end - start); + System.out.println ("ns"); + ok = false; + } + } + if (ok) + System.out.println ("ok"); + } + catch (InterruptedException x) + { + System.out.println("error: Thread interrupted."); + } + } +} diff --git a/libjava/testsuite/libjava.lang/Thread_Sleep_2.out b/libjava/testsuite/libjava.lang/Thread_Sleep_2.out new file mode 100644 index 00000000000..9766475a418 --- /dev/null +++ b/libjava/testsuite/libjava.lang/Thread_Sleep_2.out @@ -0,0 +1 @@ +ok diff --git a/libjava/testsuite/libjava.lang/Thread_Sleep_2.xfail b/libjava/testsuite/libjava.lang/Thread_Sleep_2.xfail new file mode 100644 index 00000000000..3f95317a450 --- /dev/null +++ b/libjava/testsuite/libjava.lang/Thread_Sleep_2.xfail @@ -0,0 +1 @@ +need-threads |