summaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2006-09-14 01:17:31 +0000
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2006-09-14 01:17:31 +0000
commit0bb92388895783dad3b13b8deb9d182bbedc5408 (patch)
treea5280d81d511353d5613e3482a10f15f1a24c4c1 /libjava
parent09fa572c45232c54bebd4f301df52f0112828ce4 (diff)
downloadgcc-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/ChangeLog10
-rw-r--r--libjava/posix-threads.cc39
-rw-r--r--libjava/posix.cc12
-rw-r--r--libjava/testsuite/libjava.lang/Thread_Sleep_2.java34
-rw-r--r--libjava/testsuite/libjava.lang/Thread_Sleep_2.out1
-rw-r--r--libjava/testsuite/libjava.lang/Thread_Sleep_2.xfail1
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