classpath-patches
[Top][All Lists]
Advanced

[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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]