You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by gs...@apache.org on 2008/01/15 15:34:32 UTC
svn commit: r612124 - in /harmony/enhanced/drlvm/trunk/vm: include/open/
thread/src/ vmcore/src/thread/
Author: gshimansky
Date: Tue Jan 15 06:34:30 2008
New Revision: 612124
URL: http://svn.apache.org/viewvc?rev=612124&view=rev
Log:
Applied patch from HARMONY-5352
[drlvm][thread] Thread.interrupt refactoring
Modified:
harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h
harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c
harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_condvar.c
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_native_park.c
harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_suspend.c
harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_java_basic.cpp
harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_ti_monitors.cpp
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?rev=612124&r1=612123&r2=612124&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h Tue Jan 15 06:34:30 2008
@@ -304,9 +304,9 @@
hymutex_t mutex;
/**
- * Conditional variable used to implement wait function for sleep/park;
+ * Monitor used to implement wait function for sleep/park;
*/
- hycond_t condition;
+ hythread_monitor_t monitor;
/**
* Current conditional variable thread is waiting on (used for interrupting)
@@ -344,6 +344,11 @@
*/
UDATA stacksize;
+ /**
+ * Flag of interruption
+ */
+ uint32 interrupted;
+
// Monitors
/**
@@ -556,12 +561,6 @@
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);
-
-IDATA VMCALL hythread_monitor_interrupt_wait(hythread_monitor_t mon_ptr,
- hythread_t thread);
//@}
/** @name State query
Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c?rev=612124&r1=612123&r2=612124&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c Tue Jan 15 06:34:30 2008
@@ -360,28 +360,86 @@
IDATA thread_sleep_impl(I_64 millis, IDATA nanos, IDATA interruptable) {
IDATA status;
-
- hythread_t thread = tm_self_tls;
-
+ IDATA result;
+ hythread_t self;
+ hythread_monitor_t mon;
+
if (nanos == 0 && millis == 0) {
hythread_yield();
return TM_ERROR_NONE;
- }
- // Report error in case current thread is not attached
- if (!thread) return TM_ERROR_UNATTACHED_THREAD;
-
- hymutex_lock(&thread->mutex);
- thread->state |= TM_THREAD_STATE_SLEEPING;
- status = condvar_wait_impl(&thread->condition, &thread->mutex, millis, nanos, interruptable);
- thread->state &= ~TM_THREAD_STATE_SLEEPING;
- hymutex_unlock(&thread->mutex);
+ }
+ if (!(self = hythread_self())) {
+ // Report error in case current thread is not attached
+ return TM_ERROR_UNATTACHED_THREAD;
+ }
+
+ // Grab thread monitor
+ mon = self->monitor;
+ status = hythread_monitor_enter(mon);
+ assert(status == TM_ERROR_NONE);
+ assert(mon->recursion_count == 0);
+ mon->owner = NULL;
+ mon->wait_count++;
+
+ // Set thread state
+ status = hymutex_lock(&self->mutex);
+ assert(status == TM_ERROR_NONE);
+ self->waited_monitor = mon;
+ self->state |= TM_THREAD_STATE_SLEEPING;
+ status = hymutex_unlock(&self->mutex);
+ assert(status == TM_ERROR_NONE);
+
+ do {
+ apr_time_t start;
+ assert(mon->notify_count >= 0);
+ assert(mon->notify_count < mon->wait_count);
+ start = apr_time_now();
+
+ result = condvar_wait_impl(&mon->condition, &mon->mutex, millis, nanos, interruptable);
+ if (result != TM_ERROR_NONE) {
+ break;
+ }
+ // we should not change millis and nanos if both are 0 (meaning "no timeout")
+ if (millis || nanos) {
+ apr_interval_time_t elapsed = apr_time_now() - start;
+ nanos -= (IDATA)((elapsed % 1000) * 1000);
+ if (nanos < 0) {
+ millis -= elapsed/1000 + 1;
+ nanos += 1000000;
+ } else {
+ millis -= elapsed/1000;
+ }
+ if (millis < 0) {
+ assert(status == TM_ERROR_NONE);
+ status = TM_ERROR_TIMEOUT;
+ break;
+ }
+ assert(0 <= nanos && nanos < 1000000);
+ }
+ } while(1);
+
+ // Restore thread state
+ status = hymutex_lock(&self->mutex);
+ assert(status == TM_ERROR_NONE);
+ self->state &= ~TM_THREAD_STATE_SLEEPING;
+ self->waited_monitor = NULL;
+ status = hymutex_unlock(&self->mutex);
+ assert(status == TM_ERROR_NONE);
- if (thread->request) {
+ // Release thread monitor
+ mon->wait_count--;
+ mon->owner = self;
+ assert(mon->notify_count <= mon->wait_count);
+ status = hythread_monitor_exit(mon);
+ assert(status == TM_ERROR_NONE);
+
+ if (self->request) {
hythread_safe_point();
hythread_exception_safe_point();
}
- return (status == TM_ERROR_INTERRUPT && interruptable) ? TM_ERROR_INTERRUPT : TM_ERROR_NONE;
+ return (result == TM_ERROR_INTERRUPT && interruptable)
+ ? TM_ERROR_INTERRUPT : TM_ERROR_NONE;
}
/**
@@ -595,32 +653,47 @@
*/
IDATA VMCALL hythread_struct_init(hythread_t new_thread)
{
+ char jstatus;
IDATA status;
assert(new_thread);
+ jstatus = new_thread->java_status;
if (!new_thread->os_handle) {
- // Create thread primitives
+ // new thread, create thread primitives
+ memset(new_thread, 0, sizeof(HyThread));
status = hysem_create(&new_thread->resume_event, 0, 1);
assert(status == TM_ERROR_NONE);
status = hymutex_create(&new_thread->mutex, TM_MUTEX_NESTED);
assert(status == TM_ERROR_NONE);
- status = hycond_create(&new_thread->condition);
+ status = hythread_monitor_init(&new_thread->monitor, 0);
assert(status == TM_ERROR_NONE);
- new_thread->stacksize = os_get_foreign_thread_stack_size();
} else {
- // This join should also delete thread OS handle
- int result = os_thread_free(new_thread->os_handle);
+ // old thread, reset structure
+ int result;
+ hysem_t resume;
+ hymutex_t mutex;
+ hythread_monitor_t monitor;
+
+ // release thread OS handle
+ result = os_thread_free(new_thread->os_handle);
assert(0 == result);
+
+ resume = new_thread->resume_event;
+ mutex = new_thread->mutex;
+ monitor = new_thread->monitor;
+
+ // zero new thread
+ memset(new_thread, 0, sizeof(HyThread));
+
+ new_thread->resume_event = resume;
+ new_thread->mutex = mutex;
+ new_thread->monitor = monitor;
}
+ assert(new_thread->os_handle == NULL);
- new_thread->os_handle = (osthread_t)NULL;
+ new_thread->java_status = jstatus;
new_thread->priority = HYTHREAD_PRIORITY_NORMAL;
-
- // Suspension reset
- new_thread->request = 0;
- new_thread->suspend_count = 0;
- new_thread->disable_count = 0;
- new_thread->safepoint_callback = NULL;
+ new_thread->stacksize = os_get_foreign_thread_stack_size();
hymutex_lock(&new_thread->mutex);
new_thread->state = TM_THREAD_STATE_NEW;
@@ -646,7 +719,7 @@
assert(status == TM_ERROR_NONE);
status = hymutex_destroy(&thread->mutex);
assert(status == TM_ERROR_NONE);
- status = hycond_destroy(&thread->condition);
+ status = hythread_monitor_destroy(thread->monitor);
assert(status == TM_ERROR_NONE);
memset(thread, 0, hythread_get_struct_size());
@@ -734,9 +807,7 @@
// set TERMINATED state
hymutex_lock(&thread->mutex);
- // FIXME - remove INTERRUPTED state after TM state transition complete
- thread->state = TM_THREAD_STATE_TERMINATED
- | (TM_THREAD_STATE_INTERRUPTED & thread->state);
+ thread->state = TM_THREAD_STATE_TERMINATED;
hymutex_unlock(&thread->mutex);
// detach and free thread
Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_condvar.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_condvar.c?rev=612124&r1=612123&r2=612124&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_condvar.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_condvar.c Tue Jan 15 06:34:30 2008
@@ -21,9 +21,9 @@
*/
#include "thread_private.h"
+#include <apr_atomic.h>
#include <open/hythread_ext.h>
-
/** @name Conditional variable
*/
//@{
@@ -37,32 +37,31 @@
hythread_t self;
self = tm_self_tls;
-
- // Store provided cond into current thread cond
- self->current_condition = interruptable ? cond : NULL;
// check interrupted flag
- if (interruptable && (self->state & TM_THREAD_STATE_INTERRUPTED)) {
+ if (interruptable && self->interrupted) {
// clean interrupted flag
- hymutex_lock(&self->mutex);
- self->state &= ~TM_THREAD_STATE_INTERRUPTED;
- hymutex_unlock(&self->mutex);
+ IDATA status = hythread_clear_interrupted_other(self);
+ assert(status == TM_ERROR_INTERRUPT);
return TM_ERROR_INTERRUPT;
}
+ // Store provided cond into current thread cond
+ self->current_condition = interruptable ? cond : NULL;
+
disable_count = hythread_reset_suspend_disable();
r = os_cond_timedwait(cond, mutex, ms, nano);
hythread_set_suspend_disable(disable_count);
+
self->current_condition = NULL;
// check interrupted flag
- if (interruptable && (self->state & TM_THREAD_STATE_INTERRUPTED)) {
+ if (interruptable && self->interrupted) {
// clean interrupted flag
- hymutex_lock(&self->mutex);
- self->state &= (~TM_THREAD_STATE_INTERRUPTED);
- hymutex_unlock(&self->mutex);
+ IDATA status = hythread_clear_interrupted_other(self);
+ assert(status == TM_ERROR_INTERRUPT);
return TM_ERROR_INTERRUPT;
}
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?rev=612124&r1=612123&r2=612124&view=diff
==============================================================================
--- 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 Tue Jan 15 06:34:30 2008
@@ -175,7 +175,6 @@
mon_ptr->recursion_count =0;
mon_ptr->wait_count++;
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);
@@ -186,9 +185,7 @@
assert(mon_ptr->notify_count < mon_ptr->wait_count);
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_count || hythread_interrupted(self))
- {
+ if (status != TM_ERROR_NONE || mon_ptr->notify_count) {
break;
}
// we should not change ms and nano if both are 0 (meaning "no timeout")
@@ -211,20 +208,18 @@
}
} while (1);
- // consume the notify_count unless we got an error
- // or were interrupted
+ // consume the notify_count unless we got an error (or were interrupted)
if (mon_ptr->notify_count > 0
- && ((status == TM_ERROR_NONE && !hythread_interrupted(self))
- || mon_ptr->notify_count == mon_ptr->wait_count))
+ && (status == TM_ERROR_NONE || mon_ptr->notify_count == mon_ptr->wait_count))
{
mon_ptr->notify_count--;
}
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--;
assert(mon_ptr->notify_count <= mon_ptr->wait_count);
@@ -342,33 +337,6 @@
/**
- * 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;
- }
- // While waiting on monitor, thread state TM_THREAD_STATE_INTERRUPTED
- // could already clear if condition was notified by another thread,
- // so thread state TM_THREAD_STATE_INTERRUPTED check is illegal here.
- // Just notify condition.
- return hycond_notify_all(&mon_ptr->condition);
-}
-
-
-/**
* Notify a single thread waiting on a monitor.
*
* A thread is considered to be waiting on the monitor if
@@ -386,7 +354,7 @@
return TM_ERROR_ILLEGAL_STATE;
}
if (mon_ptr->notify_count < mon_ptr->wait_count)
- mon_ptr->notify_count += 1;
+ mon_ptr->notify_count++;
return hycond_notify(&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?rev=612124&r1=612123&r2=612124&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_interrupt.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_interrupt.c Tue Jan 15 06:34:30 2008
@@ -20,10 +20,22 @@
* @brief Hythread interruption related functions
*/
-#include "thread_private.h"
#include <open/hythread_ext.h>
+#include <apr_atomic.h>
+#include "thread_private.h"
-static IDATA HYTHREAD_PROC interrupter_thread_function(void *args);
+static IDATA HYTHREAD_PROC hythread_interrupter(void *args)
+{
+ IDATA status;
+ hythread_monitor_t mon = (hythread_monitor_t)args;
+
+ status = hythread_monitor_enter(mon);
+ assert(status == TM_ERROR_NONE);
+ status = hycond_notify_all(&mon->condition);
+ assert(status == TM_ERROR_NONE);
+ hythread_exit(mon);
+ return 0;
+}
/**
* Interrupt a thread.
@@ -37,89 +49,59 @@
*/
void VMCALL hythread_interrupt(hythread_t thread) {
IDATA status;
- hymutex_lock(&thread->mutex);
- thread->state |= TM_THREAD_STATE_INTERRUPTED;
-
- if (thread == tm_self_tls) {
- hymutex_unlock(&thread->mutex);
- return;
- }
+ hythread_monitor_t mon;
+
+ apr_atomic_set32(&thread->interrupted, TRUE);
- // If thread was doing any kind of wait, notify it.
- if (thread->state & (TM_THREAD_STATE_PARKED | TM_THREAD_STATE_SLEEPING)) {
- hycond_t *condition = thread->current_condition;
- if (condition) {
- status = hycond_notify_all(condition);
+ mon = thread->waited_monitor;
+ if (mon) {
+ // If thread was doing any kind of wait, notify it.
+ if (hythread_monitor_try_enter(mon) == TM_ERROR_NONE) {
+ status = hycond_notify_all(&mon->condition);
+ assert(status == TM_ERROR_NONE);
+ status = hythread_monitor_exit(mon);
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_interrupt_wait(thread->waited_monitor, thread);
- hythread_monitor_exit(thread->waited_monitor);
} else {
- hythread_t interrupt_thread = NULL;
- status = hythread_create(&interrupt_thread, 0, 0, 0,
- interrupter_thread_function, (void *)thread);
+ status = hythread_create(NULL, 0, 0, 0,
+ hythread_interrupter, (void *)mon);
assert (status == TM_ERROR_NONE);
}
}
- hymutex_unlock(&thread->mutex);
-}
-
-static IDATA HYTHREAD_PROC 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_interrupt_wait(monitor, thread);
-
- hythread_exit(monitor);
- return 0;
-}
+} // hythread_interrupt
/**
- * Returns interrupted status and clear interrupted flag.
+ * Returns interrupted status and clear interrupted flag.
*
* @param[in] thread where to clear interrupt flag
* @returns TM_ERROR_INTERRUPT if thread was interrupted, TM_ERROR_NONE otherwise
+ * @see java.lang.Thread.interrupted()
*/
UDATA VMCALL hythread_clear_interrupted_other(hythread_t thread) {
int interrupted;
- hymutex_lock(&thread->mutex);
- interrupted = thread->state & TM_THREAD_STATE_INTERRUPTED;
- thread->state &= ~TM_THREAD_STATE_INTERRUPTED;
- hymutex_unlock(&thread->mutex);
+ assert(thread);
+ interrupted = thread->interrupted;
+ apr_atomic_set32(&thread->interrupted, FALSE);
return interrupted ? TM_ERROR_INTERRUPT : TM_ERROR_NONE;
-}
+} // hythread_clear_interrupted_other
/**
* Clear the interrupted flag of the current thread and return its previous value.
*
* @return previous value of interrupted flag: non-zero if the thread had been interrupted.
+ * @see java.lang.Thread.interrupted()
*/
UDATA VMCALL hythread_clear_interrupted() {
return hythread_clear_interrupted_other(tm_self_tls);
-}
+} // hythread_clear_interrupted
/**
* Return the value of a thread's interrupted flag.
*
* @param[in] thread thread to be queried
* @return 0 if not interrupted, non-zero if interrupted
+ * @see java.lang.Thread.isInterrupted()
*/
UDATA VMCALL hythread_interrupted(hythread_t thread) {
- int interrupted = thread->state & TM_THREAD_STATE_INTERRUPTED;
- return interrupted?TM_ERROR_INTERRUPT:TM_ERROR_NONE;
-}
+ return thread->interrupted ? TM_ERROR_INTERRUPT : TM_ERROR_NONE;
+} // hythread_interrupted
Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_park.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_park.c?rev=612124&r1=612123&r2=612124&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_park.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_park.c Tue Jan 15 06:34:30 2008
@@ -21,9 +21,9 @@
*/
#include <open/hythread_ext.h>
+#include <apr_atomic.h>
#include "thread_private.h"
-
/**
* 'Park' the current thread.
*
@@ -42,39 +42,67 @@
* @see hythread_unpark
*/
IDATA VMCALL hythread_park(I_64 millis, IDATA nanos) {
- IDATA status = 0;
- hythread_t t = tm_self_tls;
- assert(t);
-
- hymutex_lock(&t->mutex);
-
- if (t->state & TM_THREAD_STATE_UNPARKED) {
- t->state &= ~TM_THREAD_STATE_UNPARKED;
- hymutex_unlock(&t->mutex);
- return (t->state & TM_THREAD_STATE_INTERRUPTED) ? TM_ERROR_INTERRUPT : TM_ERROR_NONE;
- }
-
- t->state |= TM_THREAD_STATE_PARKED;
- status = hycond_wait_interruptable(&t->condition, &t->mutex, millis, nanos);
- t->state &= ~TM_THREAD_STATE_PARKED;
-
- if (t->request) {
- int save_count;
- hymutex_unlock(&t->mutex);
- hythread_safe_point();
- hythread_exception_safe_point();
- save_count = hythread_reset_suspend_disable();
- hymutex_lock(&t->mutex);
- hythread_set_suspend_disable(save_count);
- }
-
- //the status should be restored for j.u.c.LockSupport
- if (status == TM_ERROR_INTERRUPT) {
- t->state |= TM_THREAD_STATE_INTERRUPTED;
- }
+ IDATA status;
+ IDATA result = TM_ERROR_NONE;
+ hythread_t self = hythread_self();
+ hythread_monitor_t mon;
+ assert(self);
+
+ // Grab thread monitor
+ mon = self->monitor;
+ status = hythread_monitor_enter(mon);
+ assert(status == TM_ERROR_NONE);
+ assert(mon->recursion_count == 0);
+ mon->owner = NULL;
+ mon->wait_count++;
+
+ // Set thread state
+ status = hymutex_lock(&self->mutex);
+ assert(status == TM_ERROR_NONE);
+ self->waited_monitor = mon;
+ if (!(self->state & TM_THREAD_STATE_UNPARKED)) {
+ // if thread is not unparked stop the current thread from executing
+ self->state |= TM_THREAD_STATE_PARKED;
+ status = hymutex_unlock(&self->mutex);
+ assert(status == TM_ERROR_NONE);
+
+ do {
+ result = condvar_wait_impl(&mon->condition, &mon->mutex,
+ millis, nanos, WAIT_INTERRUPTABLE);
+ if (result != TM_ERROR_NONE
+ || (self->state & TM_THREAD_STATE_PARKED) == 0)
+ {
+ break;
+ }
+ } while (1);
+
+ // Restore thread state
+ status = hymutex_lock(&self->mutex);
+ assert(status == TM_ERROR_NONE);
+ }
+ self->state &= ~TM_THREAD_STATE_PARKED;
+ self->waited_monitor = NULL;
+ status = hymutex_unlock(&self->mutex);
+ assert(status == TM_ERROR_NONE);
+
+ // Release thread monitor
+ mon->wait_count--;
+ mon->owner = self;
+ assert(mon->notify_count <= mon->wait_count);
+ status = hythread_monitor_exit(mon);
+ assert(status == TM_ERROR_NONE);
+
+ if (self->request) {
+ hythread_safe_point();
+ hythread_exception_safe_point();
+ }
- hymutex_unlock(&t->mutex);
- return status;
+ // the status should be restored for j.u.c.LockSupport
+ if (result == TM_ERROR_INTERRUPT) {
+ apr_atomic_set32(&self->interrupted, TRUE);
+ }
+
+ return result;
}
/**
@@ -89,18 +117,30 @@
* @see hythread_park
*/
void VMCALL hythread_unpark(hythread_t thread) {
- if (thread == NULL) {
+ IDATA status;
+ hythread_monitor_t mon;
+ if (thread == NULL) {
return;
}
-
- hymutex_lock(&thread->mutex);
+
+ status = hymutex_lock(&thread->mutex);
+ assert(status == TM_ERROR_NONE);
if (thread->state & TM_THREAD_STATE_PARKED) {
- thread->state &= ~TM_THREAD_STATE_PARKED;
- hycond_notify_all(&thread->condition);
+ mon = thread->waited_monitor;
+ assert(mon);
+ // Notify parked thread
+ status = hymutex_lock(&mon->mutex);
+ assert(status == TM_ERROR_NONE);
+ status = hycond_notify_all(&mon->condition);
+ assert(status == TM_ERROR_NONE);
+ status = hymutex_unlock(&mon->mutex);
+ assert(status == TM_ERROR_NONE);
} else {
thread->state |= TM_THREAD_STATE_UNPARKED;
}
- hymutex_unlock(&thread->mutex);
+ thread->state &= ~TM_THREAD_STATE_PARKED;
+ status = hymutex_unlock(&thread->mutex);
+ assert(status == TM_ERROR_NONE);
}
Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_suspend.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_suspend.c?rev=612124&r1=612123&r2=612124&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_suspend.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_suspend.c Tue Jan 15 06:34:30 2008
@@ -342,7 +342,7 @@
hythread_exception_safe_point();
} else {
// sent an interupt signal for waiting threads
- if (thread->current_condition) {
+ if (thread->current_condition || thread->waited_monitor) {
hythread_interrupt(thread);
}
}
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_java_basic.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_java_basic.cpp?rev=612124&r1=612123&r2=612124&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_java_basic.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_java_basic.cpp Tue Jan 15 06:34:30 2008
@@ -175,14 +175,7 @@
assert(status == TM_ERROR_NONE);
// set TERMINATED thread
- status = hythread_thread_lock(native_thread);
- assert(status == TM_ERROR_NONE);
- // FIXME - remove INTERRUPTED state after TM state transition complete
- IDATA state = hythread_get_state(native_thread);
- status = hythread_set_state(native_thread,
- TM_THREAD_STATE_TERMINATED | (TM_THREAD_STATE_INTERRUPTED & state));
- assert(status == TM_ERROR_NONE);
- status = hythread_thread_unlock(native_thread);
+ status = hythread_set_state(native_thread, TM_THREAD_STATE_TERMINATED);
assert(status == TM_ERROR_NONE);
TRACE(("TM: Java thread finished: id=%d OS_handle=%p",
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_ti_monitors.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_ti_monitors.cpp?rev=612124&r1=612123&r2=612124&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_ti_monitors.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_ti_monitors.cpp Tue Jan 15 06:34:30 2008
@@ -297,7 +297,42 @@
if (!monitor) {
return TM_ERROR_INVALID_MONITOR;
}
- return hythread_monitor_wait_interruptable(monitor, millis, 0);
+
+ hythread_t native_thread = hythread_self();
+ IDATA hy_status = hythread_thread_lock(native_thread);
+ assert(hy_status == TM_ERROR_NONE);
+ IDATA state = hythread_get_state(native_thread);
+ state &= ~TM_THREAD_STATE_RUNNABLE;
+ state |= TM_THREAD_STATE_WAITING | TM_THREAD_STATE_IN_MONITOR_WAIT;
+ if (millis > 0) {
+ state |= TM_THREAD_STATE_WAITING_WITH_TIMEOUT;
+ }
+ else {
+ state |= TM_THREAD_STATE_WAITING_INDEFINITELY;
+ }
+ hy_status = hythread_set_state(native_thread, state);
+ assert(hy_status == TM_ERROR_NONE);
+ hythread_thread_unlock(native_thread);
+
+ IDATA status = hythread_monitor_wait_interruptable(monitor, millis, 0);
+
+ hy_status = hythread_thread_lock(native_thread);
+ assert(hy_status == TM_ERROR_NONE);
+ state = hythread_get_state(native_thread);
+ if (millis > 0) {
+ state &= ~TM_THREAD_STATE_WAITING_WITH_TIMEOUT;
+ }
+ else {
+ state &= ~TM_THREAD_STATE_WAITING_INDEFINITELY;
+ }
+ state &= ~(TM_THREAD_STATE_WAITING | TM_THREAD_STATE_IN_MONITOR_WAIT);
+ state |= TM_THREAD_STATE_RUNNABLE;
+ hy_status = hythread_set_state(native_thread, state);
+ assert(hy_status == TM_ERROR_NONE);
+ hy_status = hythread_thread_unlock(native_thread);
+ assert(hy_status == TM_ERROR_NONE);
+
+ return status;
} // jthread_raw_monitor_wait
/**