summaryrefslogtreecommitdiff
path: root/libjava/posix-threads.cc
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/posix-threads.cc
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/posix-threads.cc')
-rw-r--r--libjava/posix-threads.cc39
1 files changed, 25 insertions, 14 deletions
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 ();