You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by wj...@apache.org on 2007/06/06 19:40:15 UTC

svn commit: r544896 - in /harmony/enhanced/drlvm/trunk/vm: include/open/hythread_ext.h tests/smoke/thread/InterruptWait.java thread/src/thread_native_fat_monitor.c thread/src/thread_native_interrupt.c

Author: wjwashburn
Date: Wed Jun  6 10:40:15 2007
New Revision: 544896

URL: http://svn.apache.org/viewvc?view=rev&rev=544896
Log:
harmony-3641 bug is fixed.  This patch substantially reduces
the rate of spurious interrupts.  "build test2" passes for the most part


Added:
    harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/InterruptWait.java   (with props)
Modified:
    harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_fat_monitor.c
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_interrupt.c

Modified: harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h?view=diff&rev=544896&r1=544895&r2=544896
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h Wed Jun  6 10:40:15 2007
@@ -309,6 +309,9 @@
 void VMCALL hythread_native_resource_is_live(U_32);
 void VMCALL hythread_reclaim_resources();
 
+IDATA VMCALL hythread_monitor_interrupt_wait(hythread_monitor_t mon_ptr,
+					     hythread_t thread);
+
 //@}
 /** @name State query
  */

Added: harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/InterruptWait.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/InterruptWait.java?view=auto&rev=544896
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/InterruptWait.java (added)
+++ harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/InterruptWait.java Wed Jun  6 10:40:15 2007
@@ -0,0 +1,87 @@
+package thread;
+
+public class InterruptWait {
+    static boolean success = true;
+
+    public static void main(String[] args) {
+        final Lock lock = new Lock();
+        final Thread[] pool = new Thread[10];
+
+        for (int i = 0; i < pool.length; i++) {
+            pool[i] = new Thread() {
+                public void run() {
+                    lock.lock();
+                    try {
+                        Thread.sleep(100);
+                    } catch (InterruptedException e) {
+                        System.out.println(this.toString() + " interrupted while working!");
+                        success = false;
+                    }
+                    lock.unlock();
+                }
+            };
+        }
+        for (int i = 0; i < pool.length; i++) {
+            pool[i].start();
+        }
+        for (int i = 0; i < pool.length; i++) {
+            try {
+                pool[i].join();
+            } catch (InterruptedException e) {
+                System.out.println(pool[i].toString() + " interrupted while joining!");
+                success = false;
+            }
+        }
+        System.out.println(success ? "PASS" : "FAIL");
+    }
+
+    static class Lock {
+        final java.util.List<Thread> waitQueue = new java.util.LinkedList<Thread>();
+        Thread owner;
+
+        public void lock() {
+            final Thread currentThread = Thread.currentThread();
+
+            synchronized (this) {
+                if (owner == currentThread) {
+                    return;
+                }
+                if (owner == null) {
+                    owner = currentThread;
+                    return;
+                }
+                waitQueue.add(currentThread);
+
+                try {
+                    wait();
+                } catch (InterruptedException e) {
+                    // Expected, ignore.
+                    // System.out.println(Thread.currentThread().toString() + " interrupted while waiting!");
+                }
+            }
+        }
+
+        public void unlock() {
+            synchronized (this) {
+                if (owner == null) {
+                    System.out.println("ERROR at " + Thread.currentThread() + ": Can\'t unlock not locked resource");
+                    success = false;
+                }
+                if (owner != Thread.currentThread()) {
+                    System.out.println("ERROR at " + Thread.currentThread() + ": Not owner can\'t unlock resource");
+                    success = false;
+                }
+                while (!waitQueue.isEmpty()) {
+                    final Thread nextThread = waitQueue.remove(0);
+
+                    if (!nextThread.isInterrupted()) {
+                        owner = nextThread;
+                        nextThread.interrupt();
+                        return;
+                    }
+                }
+                owner = null;
+            }
+        }
+    }
+}

Propchange: harmony/enhanced/drlvm/trunk/vm/tests/smoke/thread/InterruptWait.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_fat_monitor.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_fat_monitor.c?view=diff&rev=544896&r1=544895&r2=544896
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_fat_monitor.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_fat_monitor.c Wed Jun  6 10:40:15 2007
@@ -188,7 +188,7 @@
         start = apr_time_now();
         status = condvar_wait_impl(&mon_ptr->condition, &mon_ptr->mutex, ms, nano, interruptable);
         if (status != TM_ERROR_NONE
-                || mon_ptr->notify_flag || hythread_interrupted(self))
+	                    || mon_ptr->notify_flag || hythread_interrupted(self))
             break;
         // we should not change ms and nano if both are 0 (meaning "no timeout")
         if (ms || nano) {
@@ -327,6 +327,30 @@
         return TM_ERROR_ILLEGAL_STATE;
     }
     mon_ptr->notify_flag = mon_ptr->wait_count;
+    return hycond_notify_all(&mon_ptr->condition);
+}
+
+
+/**
+ * Interrupt thread that is waiting on monitor
+ *
+ * A thread is considered to be waiting on the monitor if
+ * it is currently blocked while executing hythread_monitor_wait on 
+ * the monitor.
+ *
+ * @param[in] mon_ptr a monitor owned by thread to be interrupted
+ * @param[in] thread  thread to be interrupted
+ * @return  0 once the monitor has been signaled<br>HYTHREAD_ILLEGAL_MONITOR_STATE if the current thread does not own the monitor
+ *
+ * @see hythread_monitor_notify, hythread_monitor_notify_all, hythread_monitor_enter, hythread_monitor_wait
+ */
+IDATA VMCALL hythread_monitor_interrupt_wait(hythread_monitor_t mon_ptr,
+					     hythread_t thread) {
+    if (mon_ptr->owner != tm_self_tls) {
+        return TM_ERROR_ILLEGAL_STATE;
+    }
+
+    assert (thread->state & TM_THREAD_STATE_INTERRUPTED);
     return hycond_notify_all(&mon_ptr->condition);
 }
 

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_interrupt.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_interrupt.c?view=diff&rev=544896&r1=544895&r2=544896
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_interrupt.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_interrupt.c Wed Jun  6 10:40:15 2007
@@ -54,7 +54,7 @@
 	}
     } else if (thread->state & TM_THREAD_STATE_IN_MONITOR_WAIT) {
         if (thread->current_condition && (hythread_monitor_try_enter(thread->waited_monitor) == TM_ERROR_NONE)) {
-            hythread_monitor_notify_all(thread->waited_monitor);
+            hythread_monitor_interrupt_wait(thread->waited_monitor, thread);
             hythread_monitor_exit(thread->waited_monitor);
         } else {
             status = hythread_create(&thr, 0, 0, 0, interrupter_thread_function, (void *)thread);