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/03/04 02:25:18 UTC

svn commit: r514312 - in /harmony/enhanced/drlvm/trunk: src/test/regression/H3256/ src/test/regression/H3256/TestInterruptTimedWaiting.java vm/thread/src/thread_native_fat_monitor.c vm/thread/src/thread_native_interrupt.c vm/thread/src/thread_private.h

Author: wjwashburn
Date: Sat Mar  3 17:25:18 2007
New Revision: 514312

URL: http://svn.apache.org/viewvc?view=rev&rev=514312
Log:
Harmony-3256, fixes missing thread interrupt problem
build, build test passes on windowsxp 32 and RHEL4.0 32, gcc 4.0.2


Added:
    harmony/enhanced/drlvm/trunk/src/test/regression/H3256/
    harmony/enhanced/drlvm/trunk/src/test/regression/H3256/TestInterruptTimedWaiting.java
Modified:
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_fat_monitor.c
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_interrupt.c
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h

Added: harmony/enhanced/drlvm/trunk/src/test/regression/H3256/TestInterruptTimedWaiting.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/src/test/regression/H3256/TestInterruptTimedWaiting.java?view=auto&rev=514312
==============================================================================
--- harmony/enhanced/drlvm/trunk/src/test/regression/H3256/TestInterruptTimedWaiting.java (added)
+++ harmony/enhanced/drlvm/trunk/src/test/regression/H3256/TestInterruptTimedWaiting.java Sat Mar  3 17:25:18 2007
@@ -0,0 +1,86 @@
+public class TestInterruptTimedWaiting {
+
+	Object lock = new Object();
+	int threadCount = 100;
+	int THREAD_WAIT_TIME = 10000;
+	int WAIT_CONDITION_TIME = 2000;
+	int SLEEP_TIME = 100;
+	int loopCountBegin = WAIT_CONDITION_TIME / SLEEP_TIME;
+	int loopCount;
+	int waitedTime;
+
+	class ThreadWaiting extends Thread {
+		volatile boolean exceptionReceived = false;
+		volatile boolean working = false;
+
+		public void run () {
+			synchronized (lock) {
+				this.working = true;
+				lock.notify();
+			}
+			synchronized (this) {
+				try {
+					this.wait(THREAD_WAIT_TIME);
+				} catch (InterruptedException e) {
+					exceptionReceived = true;
+				}
+			}
+		}
+	}
+
+	public void testInterrupt_Waiting() {
+		for (int i = 0; i < threadCount; i++) {
+			ThreadWaiting t = new ThreadWaiting();
+			try {
+				synchronized (lock) {
+					t.start();
+					while (!t.working) {
+						lock.wait();
+					}
+				}
+			} catch (InterruptedException e) {
+					e.printStackTrace();
+			}
+			
+			// wait for Thread.State.TIMED_WAITING
+			Thread.State ts = t.getState();
+			loopCount = loopCountBegin;
+			while ((ts != Thread.State.TIMED_WAITING) && (loopCount-- > 0)) {
+				ts = t.getState();
+				try {
+					Thread.sleep(SLEEP_TIME);
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
+			}
+
+			// interrupt the thread
+			t.interrupt();
+
+			// wait for InteruptedException
+			loopCount = loopCountBegin;
+			while (!t.exceptionReceived && (loopCount-- > 0)) {
+				try {
+					Thread.sleep(SLEEP_TIME);
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
+			}
+			waitedTime = (loopCountBegin - loopCount) * SLEEP_TIME;
+     		System.out.println(i + " exception waited for " + waitedTime + " ms");
+
+			// check for exception received
+			if (loopCount < 0) {
+				System.out.println(i + " FAILED: waiting thread has not received the InterruptedException");
+			}
+			// check for interrupted status cleared
+			if (t.isInterrupted()) {
+				System.out.println(i + " FAILED: interrupt status has not been cleared");
+			}
+		}
+	}
+
+	public static void main(String args[]) {
+		new TestInterruptTimedWaiting().testInterrupt_Waiting();
+	}
+}
\ No newline at end of file

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=514312&r1=514311&r2=514312
==============================================================================
--- 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 Sat Mar  3 17:25:18 2007
@@ -178,6 +178,7 @@
     hymutex_lock(self->mutex);
     self->current_condition = mon_ptr->condition;
     self->state |= TM_THREAD_STATE_IN_MONITOR_WAIT;
+    self->waited_monitor = mon_ptr;
     hymutex_unlock(self->mutex);
 
     do {
@@ -212,6 +213,7 @@
     hymutex_lock(self->mutex);
     self->state &= ~TM_THREAD_STATE_IN_MONITOR_WAIT;
     self->current_condition = NULL;
+    self->waited_monitor = NULL;
     hymutex_unlock(self->mutex);
     mon_ptr->wait_count--;
 

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=514312&r1=514311&r2=514312
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_interrupt.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_interrupt.c Sat Mar  3 17:25:18 2007
@@ -23,6 +23,8 @@
 #include "thread_private.h"
 #include <open/hythread_ext.h>
 
+static int interrupter_thread_function(void *args);
+
 /** 
  * Interrupt a thread.
  * 
@@ -35,6 +37,7 @@
  */
 void VMCALL hythread_interrupt(hythread_t thread) {
     IDATA status;
+    hythread_t thr = NULL;
     hymutex_lock(thread->mutex);
     thread->state |= TM_THREAD_STATE_INTERRUPTED;
     
@@ -43,17 +46,45 @@
         return;
     }
 
-    if (thread->state
-            & (TM_THREAD_STATE_PARKED | TM_THREAD_STATE_SLEEPING
-                | TM_THREAD_STATE_IN_MONITOR_WAIT)) {
-        // If thread was doing any kind of wait, notify it.
+    // If thread was doing any kind of wait, notify it.
+    if (thread->state & (TM_THREAD_STATE_PARKED | TM_THREAD_STATE_SLEEPING)) {
         if (thread->current_condition) {
-            status = hycond_notify_all(thread->current_condition);
-            assert(status == TM_ERROR_NONE);
-        }
+	    status = hycond_notify_all(thread->current_condition);
+	    assert(status == TM_ERROR_NONE);
+	}
+    } 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_exit(thread->waited_monitor);
+        } else {
+            status = hythread_create(&thr, 0, 0, 0, interrupter_thread_function, (void *)thread);
+            assert (status == TM_ERROR_NONE);
+	}
     }
 
     hymutex_unlock(thread->mutex);
+}
+static int interrupter_thread_function(void *args) {
+    hythread_t thread = (hythread_t)args; 
+    hythread_monitor_t monitor = NULL;
+    hymutex_lock(thread->mutex);
+
+    if (thread->waited_monitor) {
+        monitor = thread->waited_monitor;
+    } else {
+        hymutex_unlock(thread->mutex);
+        hythread_exit(NULL);
+        return 0; 
+    } 
+
+    hymutex_unlock(thread->mutex);
+
+
+   hythread_monitor_enter(monitor);
+   hythread_monitor_notify_all(monitor);
+
+   hythread_exit(monitor);
+   return 0;
 }
 
 /** 

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h?view=diff&rev=514312&r1=514311&r2=514312
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h Sat Mar  3 17:25:18 2007
@@ -289,11 +289,14 @@
 // Monitors
     
     /**
+     *  Monitor this thread is waiting on now.
+     **/
+    hythread_monitor_t waited_monitor;
+
+    /**
      * ID for this thread. The maximum number of threads is governed by the size of lockword record.
      */
     IDATA thread_id;
-
-       
 
     /**
      * Memory pool in with this thread allocated