harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gshiman...@apache.org
Subject svn commit: r612124 - in /harmony/enhanced/drlvm/trunk/vm: include/open/ thread/src/ vmcore/src/thread/
Date Tue, 15 Jan 2008 14:34:32 GMT
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
 
 /**



Mime
View raw message