posix.cc (_Jv_platform_nanotime): Return nanoseconds, not microseconds; use gettimeofday when available.

* 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.

From-SVN: r116941
This commit is contained in:
Geoffrey Keating 2006-09-14 01:17:31 +00:00 committed by Geoffrey Keating
parent f5efb27f74
commit 06fcf75439
6 changed files with 81 additions and 16 deletions

View File

@ -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:

View File

@ -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 ();

View File

@ -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.

View File

@ -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.");
}
}
}

View File

@ -0,0 +1 @@
ok

View File

@ -0,0 +1 @@
need-threads