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: Fri, 31 Dec 2004 15:28:30 -0600
User-agent: Mozilla/5.0 (X11; U; FreeBSD i386; en-US; rv:1.7.3) Gecko/20041129

Jeroen Frijters wrote:
+   * A zero length sleep is equivalent to <code>Thread.yield()</code>.

I think this is not a good idea. This is not supported by any
documentation. And I agree with you that it is probably a bug in the
implementation you tested and filed a bug report for the fact that
sleep(0) seems to ignore the interrupted state of the Thread. And if we want to add this bug to our implementation (and I think
we shouldn't) why Thread.yield(), why not just return?

As we apparently can't seem to agree on this, at the very least lets
just leave open the option for the VM to do whatever it wants (as I
originally proposed).

What we can do at least is push this "interpretation" down into
VMThread.sleep() instead of Thread.sleep(), so that if a VM wants
a different interpretation at least it's easier to implement it.

Attached is the "final" patch (I hope :-)

-Archie

__________________________________________________________________________
Archie Cobbs      *        CTO, Awarix        *      http://www.awarix.com
Index: ChangeLog
===================================================================
RCS file: /cvsroot/classpath/classpath/ChangeLog,v
retrieving revision 1.3002
diff -u -r1.3002 ChangeLog
--- ChangeLog   31 Dec 2004 16:34:34 -0000      1.3002
+++ ChangeLog   31 Dec 2004 21:05:01 -0000
@@ -1,3 +1,9 @@
+2004-12-31  Archie Cobbs  <address@hidden>
+
+       * NEWS, java/lang/Thread.java, vm/reference/java/lang/VMThread.java:
+       treat Thread.sleep(0) like Thread.yield() for JDK compatibility,
+       and add a non-native implementation of VMThread.sleep().
+
 2004-12-31  Michael Koch  <address@hidden>
 
        * javax/swing/LookAndFeel.java
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        31 Dec 2004 21:05:01 -0000
@@ -14,9 +14,11 @@
 * 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.
+* Some (wrong) documentation about the behavior of VMThread.sleep(0, 0)
+  has been updated. Also, VMThread.sleep() now has a default non-native
+  implementation, but it is a generic implementation that ignores the
+  nano-seconds argument. Runtime hackers are encouraged to provide a more
+  efficient version.
 
 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       31 Dec 2004 21:05:04 -0000
@@ -803,19 +803,13 @@
    */
   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)
-      {
-       ms = 1;
-       ns = 0;
-      }
-
-    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        31 Dec 2004 21:05:04 -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)
                {
@@ -365,12 +367,51 @@
      * 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.
+     * <p>
+     * A zero length sleep is equivalent to <code>Thread.yield()</code>.
+     * This is simply for compatibility with Sun's JDK. See also
+     * <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6213203";>JDK
+     * Bug #6213203</a>.
+     *
+     * @param ms the number of milliseconds to sleep.
      * @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;
+    static void sleep(long ms, int ns) throws InterruptedException
+    {
+
+      // Round up
+      ms += (ns != 0) ? 1 : 0;
+
+      // JDK compatibility: sleep(0) is equivalent to Thread.yield()
+      if (ms == 0)
+       {
+         Thread.yield();
+         return;
+       }
+
+      // 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]