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