[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [cp-patches] Implementing Thread.sleep() via Thread.wait()
From: |
Archie Cobbs |
Subject: |
Re: [cp-patches] Implementing Thread.sleep() via Thread.wait() |
Date: |
Thu, 30 Dec 2004 17:12:46 -0600 |
User-agent: |
Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.7.3) Gecko/20041129 |
Jeroen Frijters wrote:
>>Archie Cobbs wrote:
>>Any reason we can't just implement Thread.sleep() entirely
>>in Java using Thread.wait() on the vmThread object?
>
> There are several reasons why this isn't a good idea[1], but it would
> make sense to use this approach as the default implementation of
> VMThread.sleep.
>
> [1] We're trying to design a stable -- long term -- VM interface, right?
> Clever hacks like this don't fit with that. What if a VM wants to
> support nanosecond sleep periods?
Good point.. I've reimplemented this in VMThread.sleep() instead.
Let me know what you think.
-Archie
__________________________________________________________________________
Archie Cobbs * CTO, Awarix * http://www.awarix.com
*
Confidentiality Notice: This e-mail message, including any attachments, is for
the sole use of the intended recipient(s) and may contain confidential and
privileged information. Any unauthorized review, use, disclosure or
distribution is prohibited. If you are not the intended
recipient, please contact the sender by reply e-mail and destroy all copies of
the original message.
*
Index: NEWS
===================================================================
RCS file: /cvsroot/classpath/classpath/NEWS,v
retrieving revision 1.61
diff -u -r1.61 NEWS
--- NEWS 30 Dec 2004 13:18:17 -0000 1.61
+++ NEWS 30 Dec 2004 23:11:53 -0000
@@ -14,9 +14,7 @@
* String and StringBuffer now call VMSystem.arraycopy() directly and don't
go through java.lang.System. Be careful to not initialize java.lang.System
early in the bootstrap sequence in your VM runtime interface classes.
-* VMThread.sleep() will never be called with zero arguments (don't sleep).
- VMThread does not have to do any extra argument checking. Some (wrong)
- documentation about the behavior of this method has been updated.
+* VMThread.sleep() now has a default non-native implementation.
New in release 0.12 (Nov 14, 2004)
Index: java/lang/Thread.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/Thread.java,v
retrieving revision 1.11
diff -u -r1.11 Thread.java
--- java/lang/Thread.java 30 Dec 2004 13:18:18 -0000 1.11
+++ java/lang/Thread.java 30 Dec 2004 23:11:53 -0000
@@ -768,6 +768,8 @@
* time. The Thread will not lose any locks it has during this time. There
* are no guarantees which thread will be next to run, but most VMs will
* choose the highest priority thread that has been waiting longest.
+ * <p>
+ * A zero length sleep is equivalent to <code>Thread.yield()</code>.
*
* @param ms the number of milliseconds to sleep.
* @throws InterruptedException if the Thread is (or was) interrupted;
@@ -792,6 +794,8 @@
* milli second. There is no guarantee that this thread can start up
* immediately when time expires, because some other thread may be
* active. So don't expect real-time performance.
+ * <p>
+ * A zero length sleep is equivalent to <code>Thread.yield()</code>.
*
* @param ms the number of milliseconds to sleep
* @param ns the number of extra nanoseconds to sleep (0-999999)
@@ -803,19 +807,20 @@
*/
public static void sleep(long ms, int ns) throws InterruptedException
{
+
+ // Check parameters
if (ms < 0 || ns < 0 || ns > 999999)
throw new IllegalArgumentException();
- if (ns > 0 && ms == 0)
+ // JDK compatibility: sleep(0) is equivalent to Thread.yield()
+ if (ms == 0 && ns == 0)
{
- ms = 1;
- ns = 0;
+ Thread.yield();
+ return;
}
- if (ms > 0)
- VMThread.sleep(ms, ns);
- else if (interrupted())
- throw new InterruptedException();
+ // Really sleep
+ VMThread.sleep(ms, ns);
}
/**
Index: vm/reference/java/lang/VMThread.java
===================================================================
RCS file: /cvsroot/classpath/classpath/vm/reference/java/lang/VMThread.java,v
retrieving revision 1.3
diff -u -r1.3 VMThread.java
--- vm/reference/java/lang/VMThread.java 30 Dec 2004 13:18:18 -0000
1.3
+++ vm/reference/java/lang/VMThread.java 30 Dec 2004 23:11:53 -0000
@@ -56,7 +56,6 @@
* <li>native void nativeStop(Throwable t);
* <li>native static Thread currentThread();
* <li>static native void yield();
- * <li>static native void sleep(long ms, int ns) throws InterruptedException;
* <li>static native boolean interrupted();
* </ul>
* All other methods may be implemented to make Thread handling more efficient
@@ -240,14 +239,17 @@
*/
synchronized void join(long ms, int ns) throws InterruptedException
{
- // round up
+ // Round up
ms += (ns != 0) ? 1 : 0;
- long end = System.currentTimeMillis() + ms;
+ // Compute end time, but don't overflow
+ long now = System.currentTimeMillis();
+ long end = now + ms;
+ if (end < now)
+ end = Long.MAX_VALUE;
- // Apparently, some VMs will return from wait without notify having
- // been called, so we loop and test the vmThread field in our
- // corresponding Thread object.
+ // A VM is allowed to return from wait() without notify() having been
+ // called, so we loop to handle possible spurious wakeups.
while(thread.vmThread != null)
{
// We use the VMThread object to wait on, because this is a private
@@ -255,7 +257,7 @@
wait(ms);
if(ms != 0)
{
- long now = System.currentTimeMillis();
+ now = System.currentTimeMillis();
ms = end - now;
if(ms <= 0)
{
@@ -370,7 +372,33 @@
* @throws InterruptedException if the Thread is (or was) interrupted;
* it's <i>interrupted status</i> will be cleared
*/
- static native void sleep(long ms, int ns) throws InterruptedException;
+ static void sleep(long ms, int ns) throws InterruptedException
+ {
+
+ // Round up
+ ms += (ns != 0) ? 1 : 0;
+
+ // Compute end time, but don't overflow
+ long now = System.currentTimeMillis();
+ long end = now + ms;
+ if (end < now)
+ end = Long.MAX_VALUE;
+
+ // A VM is allowed to return from wait() without notify() having been
+ // called, so we loop to handle possible spurious wakeups.
+ VMThread vt = Thread.currentThread().vmThread;
+ synchronized (vt)
+ {
+ while (true)
+ {
+ vt.wait(ms);
+ now = System.currentTimeMillis();
+ if (now >= end)
+ break;
+ ms = end - now;
+ }
+ }
+ }
/**
* Determine whether the current Thread has been interrupted, and clear