[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 11:52:39 -0600 |
User-agent: |
Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.7.3) Gecko/20041129 |
Archie Cobbs wrote:
> Any reason we can't just implement Thread.sleep() entirely in Java using
> Thread.wait() on the vmThread object? See attached patch.
Here's an updated patch that exhibits the JDK behavior of never
throwing InterruptedException for sleep(0).
Since it appears that JDK is consistent about this, I'll replace the
previous patch with this one.
-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 17:50:25 -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() is no longer needed and has been removed.
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 17:50:25 -0000
@@ -803,19 +803,41 @@
*/
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)
+ // Round up
+ ms += (ns != 0) ? 1 : 0;
+
+ // JDK compatibility: sleep(0) is equivalent to Thread.yield()
+ if (ms == 0)
{
- ms = 1;
- ns = 0;
+ Thread.yield();
+ return;
}
- if (ms > 0)
- VMThread.sleep(ms, ns);
- else if (interrupted())
- throw new InterruptedException();
+ // 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 = currentThread().vmThread;
+ synchronized (vt)
+ {
+ while (true)
+ {
+ vt.wait(ms);
+ now = System.currentTimeMillis();
+ if (now >= end)
+ break;
+ ms = end - now;
+ }
+ }
}
/**
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 17:50:25 -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)
{
@@ -354,25 +356,6 @@
static native void yield();
/**
- * Suspend the current Thread's execution for the specified amount of
- * 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>Note that 1,000,000 nanoseconds == 1 millisecond, but most VMs do
- * not offer that fine a grain of timing resolution. Besides, 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.
- *
- * @param ms the number of milliseconds to sleep. Will be at least 1.
- * @param ns the number of extra nanoseconds to sleep (0-999999)
- * @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;
-
- /**
* Determine whether the current Thread has been interrupted, and clear
* the <i>interrupted status</i> in the process.
*