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/24 14:55:08 UTC

svn commit: r522033 - in /harmony/enhanced/drlvm/trunk/vm: include/open/ interpreter/src/ jitrino/src/jet/ jitrino/src/vm/drl/ thread/src/ vmcore/src/jvmti/ vmcore/src/thread/

Author: wjwashburn
Date: Sat Mar 24 06:55:07 2007
New Revision: 522033

URL: http://svn.apache.org/viewvc?view=rev&rev=522033
Log:
H3413, refactor, cleanup of exception safepoint callback
build, build-test passes on win32 and rhel4.0, gcc 4.0.2

Modified:
    harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h
    harmony/enhanced/drlvm/trunk/vm/interpreter/src/interpreter.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp
    harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlVMInterface.cpp
    harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def
    harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_init.c
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_basic.c
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_monitors.c
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_fat_monitor.c
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_suspend.c
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_tls.c
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h
    harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_monitors.c
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_manager.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?view=diff&rev=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/include/open/hythread_ext.h Sat Mar 24 06:55:07 2007
@@ -78,7 +78,8 @@
  * Each thread managed by TM has the following fields:
  * <ul>
  * <li>    safe_region 226 boolean flag which reports whether suspend is safe at this moment or not.
- * <li>    suspend_request 226 integer indicating how many requests for suspension were made for this thread
+ * <li>    request 226 integer indicating if any request for suspension were made for this thread
+ * <li>    suspend_count 226 integer indicating how many requests for suspension were made for this thread
  * <li>    safe_region_event 226 event indicating that thread has reached safe region
  * <li>    resume_event 226 event indicating that thread needs to be awakened
  * </ul>
@@ -87,11 +88,11 @@
  * The safe thread suspension algorithm works as follows:
  * <pre>
  *   1.  GC thread invokes thread_supend() method of a thread manager which does the following:
- *       a.  If  Java thread was already requested to suspend, increase the suspend_request count and return;
- *       b.  Increase suspend_request for Java thread;
+ *       a.  If  Java thread was already requested to suspend, increase the suspend_count count and return;
+ *       b.  Increase suspend_count for Java thread;
  *       c.  If Java thread is currently in unsafe region, wait while it reaches the safe region.
  *   2.  GC thread, after completing the enumeration-related activities, calls the resume_thread() method which does the following:
- *       a.  If suspend_request was previously set, decrease the number of suspend requests;
+ *       a.  If suspend_count was previously set, decrease the number of suspend requests;
  *       b.  If the number of suspend requests reaches zero, notifies the Java thread that it can wake up now.
  *   3.  A Java thread may reach safe point, which is denoted by calling the safe_point() method in the Java thread. 
  *       The safe_point() method does the following:
@@ -191,10 +192,9 @@
 IDATA VMCALL hythread_set_private_data(hythread_t  t, void* data);
 
 UDATA VMCALL hythread_tls_get_offset(hythread_tls_key_t key);
-UDATA VMCALL hythread_tls_get_suspend_request_offset();
+UDATA VMCALL hythread_tls_get_request_offset();
 UDATA VMCALL hythread_get_thread_times(hythread_t thread, int64* pkernel, int64* puser);
 
-
 //@}
 /** @name Conditional variable
  */
@@ -218,10 +218,10 @@
 void hythread_suspend_enable();
 void hythread_suspend_disable();
 void hythread_safe_point();
+void VMCALL hythread_exception_safe_point();
 IDATA VMCALL hythread_suspend_other(hythread_t thread);
 
 IDATA VMCALL hythread_set_safepoint_callback(hythread_t thread, hythread_event_callback_proc callback);
-hythread_event_callback_proc VMCALL hythread_get_safepoint_callback(hythread_t t);
 IDATA VMCALL hythread_suspend_all(hythread_iterator_t *t, hythread_group_t group);
 IDATA VMCALL hythread_resume_all(hythread_group_t  group);
 

Modified: harmony/enhanced/drlvm/trunk/vm/interpreter/src/interpreter.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/interpreter/src/interpreter.cpp?view=diff&rev=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/interpreter/src/interpreter.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/interpreter/src/interpreter.cpp Sat Mar 24 06:55:07 2007
@@ -907,7 +907,8 @@
     frame.ip += 3;                                  \
     }                                               \
     frame.stack.pop();                              \
-    hythread_safe_point();                                \
+    hythread_safe_point();                          \
+    hythread_exception_safe_point();                \
 }
 
 DEF_OPCODE_CMP(IFEQ,==0) // Opcode_IFEQ
@@ -932,7 +933,8 @@
         DEBUG_BYTECODE(val1 << " " << val0 << " branch not taken");\
     }                                                           \
     frame.stack.pop(2);                                         \
-    hythread_safe_point();                                           \
+    hythread_safe_point();                                      \
+    hythread_exception_safe_point();                            \
 }
 
 DEF_OPCODE_IF_ICMPXX(EQ,==) // Opcode_IF_ICMPEQ OPCODE_IF_ACMPEQ
@@ -2050,6 +2052,10 @@
             << method->get_name()->bytes << "/"
             << method->get_descriptor()->bytes<< endl);
 
+    hythread_exception_safe_point();
+    if(check_current_thread_exception()) {
+        return;
+    }
     hythread_safe_point();
     interpreterInvokeVirtual(frame, method);
 }
@@ -2066,6 +2072,10 @@
             << method->get_name()->bytes << "/"
             << method->get_descriptor()->bytes << endl);
 
+    hythread_exception_safe_point();
+    if(check_current_thread_exception()) {
+        return;
+    }
     hythread_safe_point();
     interpreterInvokeInterface(frame, method);
 }
@@ -2085,6 +2095,7 @@
     // FIXME: is it possible to move the code into !cp_is_resolved condition above?
     class_initialize(method->get_class());
 
+    hythread_exception_safe_point();
     if (check_current_thread_exception()) {
         return;
     }
@@ -2105,6 +2116,11 @@
             << method->get_name()->bytes << "/"
              << method->get_descriptor()->bytes << endl);
 
+    hythread_exception_safe_point();
+    if (check_current_thread_exception()) {
+        return;
+    }
+
     hythread_safe_point();
     interpreterInvokeSpecial(frame, method);
 }
@@ -2156,6 +2172,7 @@
 static inline void
 Opcode_GOTO(StackFrame& frame) {
     hythread_safe_point();
+    hythread_exception_safe_point();
     DEBUG_BYTECODE("going to instruction");
     frame.ip += read_int16(frame.ip + 1);
 }
@@ -2163,6 +2180,7 @@
 static inline void
 Opcode_GOTO_W(StackFrame& frame) {
     hythread_safe_point();
+    hythread_exception_safe_point();
     DEBUG_BYTECODE("going to instruction");
     frame.ip += read_int32(frame.ip + 1);
 }

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp?view=diff&rev=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/jet/compiler.cpp Sat Mar 24 06:55:07 2007
@@ -1456,7 +1456,7 @@
     // Collect runtime constants
     //
     rt_array_length_offset = vector_length_offset();
-    rt_suspend_req_flag_offset = (unsigned)hythread_tls_get_suspend_request_offset();
+    rt_suspend_req_flag_offset = (unsigned)hythread_tls_get_request_offset();
     rt_vtable_offset = object_get_vtable_offset();
     
     Class_Handle clss;

Modified: harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlVMInterface.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlVMInterface.cpp?view=diff&rev=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlVMInterface.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/jitrino/src/vm/drl/DrlVMInterface.cpp Sat Mar 24 06:55:07 2007
@@ -81,7 +81,7 @@
 // TODO: free TLS key on JIT deinitilization
 uint32
 flagTLSSuspendRequestOffset(){
-    return hythread_tls_get_suspend_request_offset();
+    return hythread_tls_get_request_offset();
 }
 
 uint32

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def?view=diff&rev=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.def Sat Mar 24 06:55:07 2007
@@ -36,7 +36,7 @@
 hythread_monitor_notify
 hythread_get_priority
 hythread_tls_get
-hythread_tls_get_suspend_request_offset
+hythread_tls_get_request_offset
 hythread_tls_get_offset
 hythread_global_lock
 hythread_global_unlock
@@ -60,10 +60,10 @@
 hythread_is_suspend_enabled
 hythread_suspend_enable
 hythread_suspend_disable
+hythread_exception_safe_point
 hythread_safe_point
 hythread_suspend_other
 hythread_set_safepoint_callback
-hythread_get_safepoint_callback
 hythread_suspend_all
 hythread_resume_all
 hythread_iterator_create

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp?view=diff&rev=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/hythr.exp Sat Mar 24 06:55:07 2007
@@ -35,7 +35,7 @@
 hythread_monitor_notify;
 hythread_get_priority;
 hythread_tls_get;
-hythread_tls_get_suspend_request_offset;
+hythread_tls_get_request_offset;
 hythread_tls_get_offset;
 hythread_global_lock;
 hythread_global_unlock;
@@ -59,9 +59,9 @@
 hythread_is_suspend_enabled;
 hythread_suspend_enable;
 hythread_suspend_disable;
+hythread_exception_safe_point;
 hythread_safe_point;
 hythread_suspend_other;
-hythread_get_safepoint_callback;
 hythread_set_safepoint_callback;
 hythread_suspend_all;
 hythread_resume_all;

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_init.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_init.c?view=diff&rev=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_init.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_init.c Sat Mar 24 06:55:07 2007
@@ -246,7 +246,7 @@
 
     // make sure we do not get a global thread lock
     // while being requested to suspend
-    while (self->suspend_request) {
+    while (self->request) {
         // give up global thread lock before safepoint,
         // because this thread can be suspended at a safepoint
         r = hymutex_unlock(&TM_LIBRARY->TM_LOCK);
@@ -258,7 +258,7 @@
 
     // do not use set_suspend_disable() as we do not
     // want safe points happening under global lock
-    self->suspend_disable_count = saved_count;
+    self->disable_count = saved_count;
     return 0;
 }
 

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_basic.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_basic.c?view=diff&rev=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_basic.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_basic.c Sat Mar 24 06:55:07 2007
@@ -22,6 +22,7 @@
 
 #include <open/jthread.h>
 #include <open/hythread_ext.h>
+#include <apr_atomic.h>
 #include "open/thread_externals.h"
 #include "thread_private.h"
 #include "jni.h"
@@ -423,9 +424,6 @@
     tm_java_thread = hythread_get_private_data(tm_native_thread);
     excn = tm_java_thread->stop_exception;
     
-    tm_native_thread->suspend_request = 0;
-    hysem_post(tm_native_thread->resume_event);
-    
     jthread_throw_exception_object(excn);
 }
 
@@ -467,6 +465,7 @@
     jvmti_thread_t tm_java_thread;
     hythread_t tm_native_thread;
     JNIEnv* env;
+    IDATA res;
 
     tm_native_thread = jthread_get_native_thread(java_thread);
     tm_java_thread = hythread_get_private_data(tm_native_thread);
@@ -475,7 +474,23 @@
     env = jthread_get_JNI_env(jthread_self());
     tm_java_thread->stop_exception = (*env)->NewGlobalRef(env,excn);
     
-    return hythread_set_safepoint_callback(tm_native_thread, stop_callback);
+    res = hythread_set_safepoint_callback(tm_native_thread, stop_callback);
+
+    while (tm_native_thread->suspend_count > 0) {
+        apr_atomic_dec32(&tm_native_thread->suspend_count);
+        apr_atomic_dec32(&tm_native_thread->request);
+    }
+
+    // if there is no competition, it would be 1, but if someone else
+    // is suspending the same thread simultaneously, it could be greater than 1
+    assert(tm_native_thread->request > 0);
+
+    // notify the thread that it may wake up now,
+    // so that it would eventually reach exception safepoint
+    // and execute callback
+    hysem_post(tm_native_thread->resume_event);
+
+    return res;
 }
 
 /**

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_monitors.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_monitors.c?view=diff&rev=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_monitors.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_java_monitors.c Sat Mar 24 06:55:07 2007
@@ -88,6 +88,7 @@
     while (TM_ERROR_NONE !=unreserve_lock(lockword)) {
         hythread_yield();
         hythread_safe_point();
+        hythread_exception_safe_point();
         lockword = vm_object_get_lockword_addr(monitor);
     }
     status = hythread_thin_monitor_try_enter(lockword);
@@ -115,6 +116,7 @@
     lockword = vm_object_get_lockword_addr(monitor);
     while ((status = hythread_thin_monitor_try_enter(lockword)) == TM_ERROR_EBUSY) {
         hythread_safe_point();
+        hythread_exception_safe_point();
         lockword = vm_object_get_lockword_addr(monitor);
  
         if (is_fat_lock(*lockword)) {

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?view=diff&rev=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_basic.c Sat Mar 24 06:55:07 2007
@@ -628,12 +628,11 @@
     //ptr->big_thread_local_storage = (void **)calloc(1, sizeof(void*)*tm_tls_capacity);
     
     // Suspension
-    ptr->suspend_request = 0;
-    ptr->suspend_disable_count = 0;
+    ptr->request = 0;
+    ptr->suspend_count = 0;
+    ptr->disable_count = 0;
     status = hylatch_create(&ptr->join_event, 1);
     assert(status == TM_ERROR_NONE);
-    status = hylatch_create(&ptr->safe_region_event, 1);
-    assert(status == TM_ERROR_NONE);
     status = hysem_create(&ptr->resume_event, 0, 1);
     assert(status == TM_ERROR_NONE);
     status = hymutex_create(&ptr->mutex, TM_MUTEX_NESTED);
@@ -653,23 +652,27 @@
         assert(!r);
     }
 
+    hymutex_lock(&thread->mutex);
+
     thread->os_handle  = (osthread_t)NULL;
     thread->priority   = HYTHREAD_PRIORITY_NORMAL;
     // not implemented
     //ptr->big_thread_local_storage = (void **)calloc(1, sizeof(void*)*tm_tls_capacity);
 
     // Suspension
-    thread->suspend_request = 0;
-    thread->suspend_disable_count = 0;
+    thread->request = 0;
+    thread->suspend_count = 0;
+    thread->disable_count = 0;
     thread->safepoint_callback = NULL;
+    thread->state = TM_THREAD_STATE_ALLOCATED;
+
+    hymutex_unlock(&thread->mutex);
+
     status = hylatch_set(thread->join_event, 1);
     assert(status == TM_ERROR_NONE);
-    status = hylatch_set(thread->safe_region_event, 1);
-    assert(status == TM_ERROR_NONE);
     status = hysem_set(thread->resume_event, 0);
     assert(status == TM_ERROR_NONE);
     
-    thread->state = TM_THREAD_STATE_ALLOCATED;
 }
 
 // Wrapper around user thread start proc. Used to perform some duty jobs 

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=522033&r1=522032&r2=522033
==============================================================================
--- 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 24 06:55:07 2007
@@ -218,10 +218,11 @@
     hymutex_unlock(&self->mutex);
     mon_ptr->wait_count--;
 
-    if (self->suspend_request) {
+    if (self->request) {
         int save_count;
         hymutex_unlock(&mon_ptr->mutex);
         hythread_safe_point();
+        hythread_exception_safe_point();
         save_count = reset_suspend_disable();
         hymutex_lock(&mon_ptr->mutex);
         set_suspend_disable(save_count);

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?view=diff&rev=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_suspend.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_suspend.c Sat Mar 24 06:55:07 2007
@@ -37,385 +37,444 @@
 /**
  * Returns non-zero if thread is suspended.
  */
-IDATA VMCALL hythread_is_suspend_enabled() {
-    return tm_self_tls->suspend_disable_count == 0;
+IDATA VMCALL hythread_is_suspend_enabled()
+{
+    return tm_self_tls->disable_count == 0;
 }
 
 
 /**
  * Denotes the beginning of the code region where safe suspension is possible.
  *
- * First, this method sets the suspend_enabled state flag to true.
- * If there was a suspension request set for this thread, this method notifies the 
- * requesting thread that a safe region is reached.
+ * The method decreases the disable_count field. The disable_count could be
+ * recursive, so safe suspension region is enabled on value 0.
+ *
  * <p>
- * A thread marks itself with functions tmn_suspend_enable() and tmn_suspend_disable() in order
- * to denote a safe region of code. It may also call safe_point() method to denote a selected 
+ * A thread marks itself with functions hythread_suspend_enable()
+ * and hythread_suspend_disable() in order to denote a safe region of code.
+ * A thread may also call hythread_safe_point() method to denote a selected
  * point where safe suspension is possible.
  */
-void VMCALL hythread_suspend_enable() {
-    register hythread_t thread;
+void VMCALL hythread_suspend_enable()
+{
     assert(!hythread_is_suspend_enabled());
 
 #ifdef FS14_TLS_USE
-    __asm { 
-         mov eax, fs:[0x14] 
-         dec [eax]HyThread.suspend_disable_count
-         mov eax, [eax]HyThread.suspend_request
-         test eax, eax
-         jnz suspended
-        
-    } 
-    return;
-
-suspended:
-    thread=tm_self_tls;
-
-#else 
-    thread=tm_self_tls;
-    thread->suspend_disable_count--;
-
+    // the macros could work for WIN32
+    __asm {
+        mov eax, fs:[0x14]
+        dec[eax] HyThread.disable_count
+    }
+#else
+    {
+        register hythread_t thread = tm_self_tls;
+        thread->disable_count--;
+    }
 #endif
- //   if (!thread->suspend_request  || thread->suspend_disable_count!=0) {
-   //     return;
-   // }
-        
-   // hylatch_count_down(thread->safe_region_event);
 }
 
 /**
  * Denotes the end of the code region where safe suspension was possible.
  *
- * This method sets the suspend_enabled state flag to false and then invokes
- * tmn_safe_point().
+ * The method increases the disable_count field. The disable_count could be
+ * recursive, so safe suspension region is enabled on value 0.
+ * If there was a suspension request set for this thread, the method invokes
+ * hythread_safe_point().
  * <p>
- * A thread marks itself with functions tmn_suspend_enable() and tmn_suspend_disable() in order
- * to denote a safe region of code. It may also call safe_point() method to denote a selected 
+ * A thread marks itself with functions hythread_suspend_enable()
+ * and hythread_suspend_disable() in order to denote a safe region of code.
+ * A thread may also call hythread_safe_point() method to denote a selected
  * point where safe suspension is possible.
  */
 void VMCALL hythread_suspend_disable()
-{   
+{
     register hythread_t thread;
-#ifndef NDEBUG
+
     // Check that current thread is in default thread group.
-    // Justification: GC suspends and enumerates threads from default group only.
+    // Justification: GC suspends and enumerates threads from
+    // default group only.
     assert(tm_self_tls->group == TM_DEFAULT_GROUP);
-#endif
 
 #ifdef FS14_TLS_USE
-    __asm { 
-         mov eax, fs:[0x14] 
-         inc [eax]HyThread.suspend_disable_count
-         mov eax, [eax]HyThread.suspend_request
-         test eax, eax
-         jnz suspended
-        
-    } 
+    // the macros could work for WIN32
+    __asm {
+        mov eax, fs:[0x14]
+        inc[eax] HyThread.disable_count
+        mov eax,[eax] HyThread.request
+        test eax, eax
+        jnz suspended
+    }
     return;
 
-suspended:
-    thread=tm_self_tls;
+  suspended:
+    thread = tm_self_tls;
 
-#else 
-    thread=tm_self_tls;
-    thread->suspend_disable_count++;
+#else
+    thread = tm_self_tls;
+    thread->disable_count++;
 #endif
 
-    if (!thread->suspend_request  || thread->suspend_disable_count!=1) {
-        return;
+    if (thread->request && thread->disable_count == 1) {
+        // enter to safe point if suspend request was set
+        // and suspend disable was made a moment ago
+        // (it's a point of entry to the unsafe region)
+        thread_safe_point_impl(thread);
     }
-    thread_safe_point_impl(thread);
+    return;
 }
 
+/**
+ * Denotes a single point where safe exception throwing is possible.
+ */
+void VMCALL hythread_exception_safe_point()
+{
+    hythread_t self = tm_self_tls;
+    int gc_disable_count;
+    hythread_event_callback_proc callback_func;
+
+    if (!self->safepoint_callback) {
+        return;
+    }
+
+    /**
+     * There is a contract between disable_count value and Java code:
+     * during Java code execution disable_count should be equal to 1.
+     * It means that garbage collection while in native code can only
+     * take place when the native code makes disable_count equal to zero.
+     * To do this, the native code must guarantee that the GC is able to
+     * see all live references the native code is working with. And that
+     * the native code will not read/write live references while disable_count
+     * is equal to zero. This happens within suspension safe points or
+     * within VM helpers safe regions.
+     *
+     * Safepoint callback function could call Java code. If this happens,
+     * disable_count must be set to 1 before callback function execution.
+     *
+     * Field disable_count cannot be changed by another thread. Its value
+     * changes only by the same thread. So there is no race condition or
+     * separate usage in setting disable_count to 1.
+     */
+    gc_disable_count = self->disable_count;
+    self->disable_count = 1;
+
+    // Clear callback (this is one-time event)
+    callback_func = self->safepoint_callback;
+    self->safepoint_callback = NULL;
+
+    // remove safe point callback request
+    apr_atomic_dec32(&self->request);
+
+    callback_func();
+
+    // restore disable_count
+    self->disable_count = gc_disable_count;
+
+    return;
+}
 
 
 /**
  * Denotes a single point where safe suspension is possible.
  *
  * If there was a suspension request set for this thread, this method notifies
- * the requesting thread and then blocks until someone calls the tmn_resume() 
- * for this thread.
+ * the requesting thread and then blocks until someone calls the
+ * hythread_resume() function for this thread.
  * <p>
- * A thread marks itself with functions tmn_suspend_enable() and tmn_suspend_disable() in order
- * to denote a safe region of code. It may also call safe_point() method to denote a selected 
+ * A thread marks itself with functions hythread_suspend_enable()
+ * and hythread_suspend_disable() in order to denote a safe region of code.
+ * A thread may also call hythread_safe_point() method to denote a selected
  * point where safe suspension is possible.
  */
-void VMCALL hythread_safe_point() {
+void VMCALL hythread_safe_point()
+{
     thread_safe_point_impl(tm_self_tls);
 }
 
-static void thread_safe_point_impl(hythread_t thread) { 
-    hythread_event_callback_proc callback_func;
-    if (thread->suspend_request >0) {
-        
-        int old_status = thread->suspend_disable_count;
-        do {
-            TRACE(("TM: safe point enter: thread: %p count: %d dis count: %d", 
-                thread, thread->suspend_request, thread->suspend_disable_count));
-            
-            if (thread->safepoint_callback) {
-                thread->suspend_disable_count = 1;
-                // Clear callback (this is one-time event)
-                callback_func = thread->safepoint_callback;
-                thread->safepoint_callback = NULL;
-                
-                // since set callback suspended the thread
-                // restore its original state
-                hythread_resume(tm_self_tls);
-                callback_func();
-            }
-            
-            thread->suspend_disable_count = 0;
-            
-            apr_memory_rw_barrier();
-            // code for Ipf that support StackIterator and immediate suspend
-            // notify suspender
-            //  hylatch_count_down(thread->safe_region_event);
-
-            // wait for resume event
-            hysem_wait(thread->resume_event);
-            TRACE(("TM: safe point resume: thread: %p count: %d", thread, thread->suspend_request));
-
-            thread->suspend_disable_count = old_status;
-            apr_memory_rw_barrier();
-        } while (thread->suspend_request >0);
+/**
+ * Denotes a single point where safe suspension is
+ * possible for a given thread.
+ */
+static void thread_safe_point_impl(hythread_t thread)
+{
+    int gc_disable_count;
+
+    if (!thread->suspend_count) {
+        return;
     }
-} // thread_safe_point_impl
 
+    // the thread is entering to the safe region,
+    // set disable count to 0 (safe region value)
+    gc_disable_count = thread->disable_count;
+    thread->disable_count = 0;
+    apr_memory_rw_barrier();
+
+    do {
+        TRACE(("safe point enter: thread: %p, suspend_count: %d, request: %d",
+               thread, thread->suspend_count, thread->request));
+
+        // wait for resume event
+        hysem_wait(thread->resume_event);
+
+        TRACE(("safe point exit: thread: %p, suspend_count: %d, request: %d",
+               thread, thread->suspend_count, thread->request));
+    } while (thread->suspend_count);
 
-// the function start suspension.
-// call wait_safe_region_event() should be called to wait for safe region or safe point.
-// the function do not suspend self.
-static void send_suspend_request(hythread_t thread) {
-
-    assert(thread->suspend_request >=0);
-    // already suspended?
-    if (thread->suspend_request > 0) {
-        apr_atomic_inc32((apr_uint32_t *)&(thread->suspend_request));
-        return;
-    }               
-                
-    //we really need to suspend thread.
+    // restore disable_count value
+    thread->disable_count = gc_disable_count;
 
-    hysem_set(thread->resume_event, 0);
-                
-    apr_atomic_inc32((apr_uint32_t *)&(thread->suspend_request));
+    return;
+} // thread_safe_point_impl
 
-    os_thread_yield_other(thread->os_handle);
 
-    TRACE(("TM: suspend request sent: %p request count: %d",thread , thread->suspend_request));
+/**
+ * Starts suspension of a given thread.
+ * The method increases suspend_count and sets request.
+ * Calling wait_safe_region_event() could be called
+ * to wait for safe region or safe point.
+ */
+static void send_suspend_request(hythread_t thread)
+{
+    // increment suspend count
+    apr_atomic_inc32(&thread->suspend_count);
+    apr_atomic_inc32(&thread->request);
 }
 
+/**
+ * Waits until a given thread reaches a safe region.
+ * The method is called after send_suspend_request() function
+ * as the second part of suspension.
+ */
+static IDATA wait_safe_region_event(hythread_t thread)
+{
+    hythread_t self = tm_self_tls;
+
+    assert(thread->suspend_count);
+    assert(thread != self);
 
-// the second part of suspension
-// blocked in case was selfsuspended.
-static IDATA wait_safe_region_event(hythread_t thread) {
-    assert(thread->suspend_request >= 1);
-    if(thread == tm_self_tls) {
-        TRACE(("TM: suspend wait self exit thread: %p request count: %d",thread , thread->suspend_request));
-        return TM_ERROR_NONE;
-    }               
-                // we need to wait for notification only in case the thread is in the unsafe/disable region
-    while (thread->suspend_disable_count) {
+    // We need to wait for notification only in case the thread is in
+    // the unsafe/disable region. All threads should be stoped in
+    // safepoints or be in safe region.
+    while (thread->disable_count != 0) {
         // HIT cyclic suspend
-        if(tm_self_tls->suspend_request > 0) {
-             return TM_ERROR_EBUSY; 
+        if (self->request) {
+            return TM_ERROR_EBUSY;
         }
         hythread_yield();
     }
-    TRACE(("TM: suspend wait exit safe region thread: %p request count: %d",thread , thread->suspend_request));
+    TRACE(("suspend wait exit safe region thread: "
+           "%p, suspend_count: %d, request: %d",
+           thread, thread->suspend_count, thread->request));
+    hymutex_lock(&thread->mutex);
     thread->state |= TM_THREAD_STATE_SUSPENDED;
-    return TM_ERROR_NONE; 
+    hymutex_unlock(&thread->mutex);
+    return TM_ERROR_NONE;
 }
 
 /**
  * Suspends the current thread. 
  * 
  * Stop the current thread from executing until it is resumed.
- * 
- * @return none
  *
  * @see hythread_resume
  */
-void VMCALL hythread_suspend() {
-    hythread_t thread = tm_self_tls;
+void VMCALL hythread_suspend()
+{
+    hythread_t self = tm_self_tls;
 
-    apr_atomic_inc32((apr_uint32_t *)&(thread->suspend_request));
+    send_suspend_request(self);
 
-    hythread_safe_point();
-}
+    hymutex_lock(&self->mutex);
+    self->state |= TM_THREAD_STATE_SUSPENDED;
+    hymutex_unlock(&self->mutex);
 
+    thread_safe_point_impl(self);
+}
 
 /**
  * Safely suspends the <code>thread</code> execution.
  *
- * This method is a SAFE_POINT
- *
  * The safe suspension acts as follows:
  * <ul>
  * <li>
  * If the <code>thread</code> is currently running in safe code region, this
  * method immediately returns back.
  * The <code>thread</code> itself runs until it reaches the end of safe region
- * and then blocks until someone calls tmn_resume() for it.
+ * and then blocks until someone calls hythread_resume() for it.
  * <li>
  * If the <code>thread</code> is currently in unsafe region, this
  * method blocks until the <code>thread</code> either reaches the beginning 
  * of a safe region, or reaches a safe point. 
- * Once reached safe point or end of safe region, the<code>thread</code> blocks 
- * until someone calls tmn_resume() for it.
+ * Once reached safe point or end of safe region, the<code>thread</code> blocks
+ * until someone calls hythread_resume() for it.
  * </ul>
- * A thread marks itself with functions tmn_suspend_enable() and tmn_suspend_disable() in order
- * to denote a safe region of code. It may also call safe_point() method to denote a selected 
+ * A thread marks itself with functions hythread_suspend_enable()
+ * and hythread_suspend_disable() in order to denote a safe region of code.
+ * A thread may also call hythread_safe_point() method to denote a selected
  * point where safe suspension is possible.
  *
  * @param[in] thread thread to be suspended
  * @return TM_ERROR_EBUSY if deadlock, TM_ERROR_NONE if OK  
  */
-IDATA VMCALL hythread_suspend_other(hythread_t thread) {
-    hythread_t self;
-    self = tm_self_tls;
-    TRACE(("TM: suspend one enter thread: %p self: %p request count: %d",thread , tm_self_tls, thread->suspend_request));
+IDATA VMCALL hythread_suspend_other(hythread_t thread)
+{
+    hythread_t self = tm_self_tls;
+
+    TRACE(("suspend enter, self: %p, thread: %p, "
+           "suspend_count: %d, request: %d", self, thread,
+           thread->suspend_count, thread->request));
+
     if (self == thread) {
+        // suspend self
         hythread_suspend();
-        return TM_ERROR_NONE; 
+        return TM_ERROR_NONE;
     }
 
+    // suspend another thread
     send_suspend_request(thread);
-    while (wait_safe_region_event(thread)!=TM_ERROR_NONE) {
-        if (self->suspend_request>0) {
-            hythread_resume(thread);
-            return TM_ERROR_EBUSY;
-        }
-    }
-    TRACE(("TM: suspend one exit thread: %p request count: %d",thread , thread->suspend_request));
-        
+    if (wait_safe_region_event(thread) != TM_ERROR_NONE) {
+        hythread_resume(thread);
+        return TM_ERROR_EBUSY;
+    }
+    TRACE(("suspend exit, self: %p, thread: %p, "
+           "suspend_count: %d, request: %d", self, thread,
+           thread->suspend_count, thread->request));
     return TM_ERROR_NONE;
 }
 
 /**
- * Resume a thread.
+ * Resumes a thread.
  *
  * Take a threads out of the suspended state.
- *
  * If the thread is not suspended, no action is taken.
  *
  * @param[in] thread a thread to be resumed
- * @return none
  *
  * @see hythread_create, hythread_suspend
  */
-void VMCALL hythread_resume(hythread_t thread) {
-    TRACE(("TM: start resuming: %p request count: %d",thread , thread->suspend_request));
-    // If there was request for suspension, decrease the request counter
-    //printf("resume other now lock %d  %d  %d  %d\n",tm_self_tls->thread_id,tm_self_tls->suspend_disable_count,thread->thread_id,thread->suspend_disable_count);
-    if (thread->suspend_request > 0) {
-        if (thread->safepoint_callback && thread->suspend_request < 2) return;
-        apr_atomic_dec32((apr_uint32_t *)&(thread->suspend_request));
-        if (thread->suspend_request == 0) {
-            // Notify the thread that it may wake up now
-            hysem_post(thread->resume_event);            
-            TRACE(("TM: resume one thread: %p request count: %d",thread , thread->suspend_request));
-            thread->state &= ~TM_THREAD_STATE_SUSPENDED;
+void VMCALL hythread_resume(hythread_t thread)
+{
+    int count;
+
+    TRACE(("start resume, self: %p, thread: %p, "
+           "suspend_count: %d, request: %d", self, thread,
+           thread->suspend_count, thread->request));
+
+    do {
+        count = thread->suspend_count;
+        if (!count) {
+            return;
         }
+    } while (apr_atomic_cas32(&thread->suspend_count, count - 1, count) != count);
+
+    // If there was request for suspension,
+    // decrease the suspend counter and remove request
+    apr_atomic_dec32(&thread->request);
+
+    if (thread->suspend_count) {
+        return;
     }
-    //printf("resume other now lock-compl %d  %d  %d  %d\n",tm_self_tls->thread_id,tm_self_tls->suspend_disable_count,thread->thread_id,thread->suspend_disable_count);
+
+    // change thread state
+    hymutex_lock(&thread->mutex);
+    thread->state &= ~TM_THREAD_STATE_SUSPENDED;
+    hymutex_unlock(&thread->mutex);
+
+    TRACE(("sent resume, self: %p, thread: %p, "
+           "suspend_count: %d, request: %d", self, thread,
+           thread->suspend_count, thread->request));
+
+    // notify the thread that it may wake up now
+    hysem_post(thread->resume_event);
+    return;
 }
 
 /**
  * Sets safepoint callback function.
  * 
- * Callback function is executed at safepoint in case there was a suspension request.
+ * Callback function is executed at safepoint in case there was
+ * a safepoint callback request.
  *  
  * @param[in] thread thread where callback needs to be executed
  * @param[in] callback callback function
  */
-IDATA hythread_set_safepoint_callback(hythread_t thread, tm_thread_event_callback_proc callback) {
-    IDATA status;
-    while (apr_atomic_casptr((volatile void **)&thread->safepoint_callback, (void *)callback, (void *)NULL) != NULL);
-    if (tm_self_tls == thread) {
-        int old_status = thread->suspend_disable_count;
-        thread->suspend_disable_count = 1;
-        hythread_suspend();
-        thread->suspend_disable_count = old_status;
-    } else {
-        //we will not have notification from the
-        //target thread if safe_point call back will not exit
-        ////
-        send_suspend_request(thread);
-        //let the thread execute safe point in the case it's already suspended
-        ////
-        status = hysem_post(thread->resume_event);
-        
-    }
-    
-    if (thread->current_condition) {
-        status=hycond_notify_all(thread->current_condition);   
-        assert(status == TM_ERROR_NONE);
+IDATA hythread_set_safepoint_callback(hythread_t thread,
+                                      tm_thread_event_callback_proc callback)
+{
+    hythread_t self = tm_self_tls;
+
+    while (apr_atomic_casptr((volatile void **) &thread->safepoint_callback,
+                             callback, NULL) != NULL)
+    {
+        thread_safe_point_impl(self);
+        hythread_yield();
     }
 
-    return TM_ERROR_NONE;
-}
+    // set safe point callback request
+    apr_atomic_inc32(&thread->request);
 
-/**
- * Returns safepoint callback function.
- * 
- * @param[in] t thread where callback needs to be executed
- * @return callback function currently installed, or NULL if there was none
- */
-hythread_event_callback_proc VMCALL hythread_get_safepoint_callback(hythread_t t) {
-    return t->safepoint_callback;
+    if (self == thread) {
+        hythread_exception_safe_point();
+    } else {
+        // sent an interupt signal for waiting threads
+        if (thread->current_condition) {
+            IDATA UNREF status = hycond_notify_all(thread->current_condition);
+            assert(status == TM_ERROR_NONE);
+        }
+    }
+    return TM_ERROR_NONE;
 }
 
 /**
  * Helps to safely suspend the threads in the selected group.
  *
- * This method sets a suspend request for the every thread in the group 
- * and then returns the iterator that can be used to traverse through the suspended threads.
- * Each invocation of the tmn_iterator_next() method on the iterator will return the next 
- * suspended thread.
+ * The method sets a suspend request for the every thread in the group
+ * and then returns the iterator that can be used to traverse through
+ * the suspended threads.
+ * Each invocation of the hythread_iterator_next() method on the iterator
+ * will return the next suspended thread.
  *
- * @param[out] t iterator 
+ * @param[out] iter_ptr iterator
  * @param[in] group thread group to be suspended
  */
-IDATA VMCALL hythread_suspend_all(hythread_iterator_t *t, hythread_group_t group) {
+IDATA VMCALL hythread_suspend_all(hythread_iterator_t* iter_ptr,
+                                  hythread_group_t group)
+{
     hythread_t self = tm_self_tls;
     hythread_t next;
     hythread_iterator_t iter;
-    TRACE(("TM: suspend all"));
-    
-    self = tm_self_tls;
+    TRACE(("suspend all threads"));
+
     // try to prevent cyclic suspend dead-lock
-    while (self->suspend_request > 0) {
-        thread_safe_point_impl(self);
-    }
+    thread_safe_point_impl(self);
 
-    iter = hythread_iterator_create(group);
     // send suspend requests to all threads
-    TRACE(("TM: send suspend requests"));
+    TRACE(("send suspend requests"));
+    iter = hythread_iterator_create(group);
     while ((next = hythread_iterator_next(&iter)) != NULL) {
         if (next != self) {
             send_suspend_request(next);
-        }       
+        }
     }
     hythread_iterator_reset(&iter);
-    // all threads should be stopped in safepoints or be in safe region.
-    TRACE(("TM: wait suspend responses"));
+
+    // all threads should be stoped in safepoints or be in safe region.
+    TRACE(("wait suspend responses"));
     while ((next = hythread_iterator_next(&iter)) != NULL) {
-        if (next != self) {
-            while (wait_safe_region_event(next)!=TM_ERROR_NONE) {
-                thread_safe_point_impl(tm_self_tls);
-                hythread_yield();
-            }
-        }       
+        if (next == self) {
+            continue;
+        }
+        while (wait_safe_region_event(next) != TM_ERROR_NONE) {
+            thread_safe_point_impl(self);
+            hythread_yield();
+        }
     }
-    
+
     hythread_iterator_reset(&iter);
     hythread_iterator_release(&iter);
-    if (t) {
-        *t=iter;
+    if (iter_ptr) {
+        *iter_ptr = iter;
     }
-       
+
     return TM_ERROR_NONE;
 }
 
@@ -426,42 +485,54 @@
  *
  * @param[in] group thread group to be resumed
  */
-IDATA VMCALL hythread_resume_all(hythread_group_t  group) {
+IDATA VMCALL hythread_resume_all(hythread_group_t group)
+{
     hythread_t self = tm_self_tls;
     hythread_t next;
     hythread_iterator_t iter;
     iter = hythread_iterator_create(group);
-    TRACE(("TM: resume all"));
+    TRACE(("resume all threads"));
+
     // send suspend requests to all threads
     while ((next = hythread_iterator_next(&iter)) != NULL) {
         if (next != self) {
             hythread_resume(next);
-        }       
+        }
     }
-        
-    hythread_iterator_release(&iter); 
+    hythread_iterator_release(&iter);
     return TM_ERROR_NONE;
 }
 
 
-// Private functionality
-
-int reset_suspend_disable() {
+/**
+ * Reset disable_count for currect thread.
+ * The method begins suspension safe region.
+ * Field disable_count is restored in set_suspend_disable() function.
+ */
+int reset_suspend_disable()
+{
     hythread_t self = tm_self_tls;
-    int dis = self->suspend_disable_count;
-    self->suspend_disable_count = 0;
-    if (self->suspend_request >0) {
-        // notify suspender
-        hylatch_count_down(self->safe_region_event);
-    }
-    return dis;
+    int disable_count = self->disable_count;
+    self->disable_count = 0;
+
+    return disable_count;
 }
 
-void set_suspend_disable(int count) {
+/**
+ * Restores disable_count for current thread,
+ * which was reset in reset_suspend_disable() function
+ * If restored value ends suspension safe region
+ * and there was a suspension request set for this thread,
+ * the method invokes hythread_safe_point() function.
+ */
+void set_suspend_disable(int count)
+{
     hythread_t self = tm_self_tls;
-    assert(count>=0);
-    self->suspend_disable_count = count;
-    if (count) {
+
+    assert(count >= 0);
+    self->disable_count = count;
+
+    if (count && self->suspend_count) {
         thread_safe_point_impl(self);
     }
 }

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_tls.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_tls.c?view=diff&rev=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_tls.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_native_tls.c Sat Mar 24 06:55:07 2007
@@ -114,10 +114,10 @@
 }
 
 /**
- * Returns 'suspend_request' field offset in HyThread struct
+ * Returns 'request' field offset in HyThread struct
  */
-UDATA VMCALL hythread_tls_get_suspend_request_offset() {
-    return (UDATA)&((hythread_t)0)->suspend_request;
+UDATA VMCALL hythread_tls_get_request_offset() {
+    return (UDATA)&((hythread_t)0)->request;
 }
 
 /**

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=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_private.h Sat Mar 24 06:55:07 2007
@@ -134,8 +134,6 @@
     hycond_t  nondaemon_thread_cond;
 } HyThreadLibrary;
 
-
-
 /**
  * Native thread control structure.
  */
@@ -156,30 +154,70 @@
 // Suspension 
     
     /**
+     * Number of requests made for this thread, it includes both
+     * suspend requests and safe point callback requests.
+     * The field is modified by atomic operations.
+     *
+     * Increment in functions:
+     *    1. send_suspend_request()
+     *          - sets suspend request for a given thread
+     *    2. hythread_set_safepoint_callback()
+     *          - sets safe point callback request for a given thread
+     *
+     * Decrement in functions:
+     *    1. hythread_resume()
+     *          - removes suspend request for a given thread
+     *    2. hythread_exception_safe_point()
+     *          - removes safe point callback request for current thread
+     */
+    int32 request;
+
+    /**
      * Number of suspend requests made for this thread.
+     * The field is modified by atomic operations.
+     *
+     * After increment/decrement of suspend_count, request field
+     * should be incremented/decremented too.
      */
-    int32 suspend_request;
+    int32 suspend_count;
     
     /**
-     * Flag indicating that thread can safely be suspended.
+     * Field indicating that thread can safely be suspended.
+     * Safe suspension is enabled on value 0.
+     *
+     * The disable_count is increased/decreaded in
+     * hythread_suspend_disable()/hythread_suspend_enable() function
+     * for current thread only.
+     *
+     * Also disable_count could be reset to value 0 and restored in
+     * reset_suspend_disable()/set_suspend_disable() function
+     * for current thread only.
+     *
+     * Function hythread_exception_safe_point() sets disable_count to
+     * value 1 before safe point callback function calling and restores
+     * it after the call.
+     *
+     * Function thread_safe_point_impl() sets disable_count to
+     * value 0 before entering to the safe point and restores it
+     * after exitting.
      */
-    int16 suspend_disable_count;
+    int16 disable_count;
         
     /**
-     * Event used to notify interested threads whenever thread enters the safe region.
+     * Function to be executed at safepoint upon thread resume.
+     *
+     * Field is set in hythread_set_safepoint_callback() function
+     * and reset hythread_exception_safe_point() function.
+     *
+     * After set/reset of safepoint_callback, request field
+     * should be incremented/decremented too.
      */
-    hylatch_t safe_region_event;
+    hythread_event_callback_proc safepoint_callback;
 
     /**
      * Event used to notify suspended thread that it needs to wake up.
-     */   
-    hysem_t resume_event;
-
-    /**
-     * Function to be executed at safepoint upon thread resume.
      */
-    hythread_event_callback_proc safepoint_callback;
-
+    hysem_t resume_event;
 
 // Basic manipulation fields
 

Modified: harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_monitors.c
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_monitors.c?view=diff&rev=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_monitors.c (original)
+++ harmony/enhanced/drlvm/trunk/vm/thread/src/thread_ti_monitors.c Sat Mar 24 06:55:07 2007
@@ -115,6 +115,7 @@
     }
     stat = hythread_monitor_enter(monitor);
     hythread_safe_point();
+    hythread_exception_safe_point();
     return stat;
 }
 
@@ -145,6 +146,7 @@
     }
     stat = hythread_monitor_exit(monitor);
     hythread_safe_point();
+    hythread_exception_safe_point();
     return stat;
 }
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp?view=diff&rev=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_break.cpp Sat Mar 24 06:55:07 2007
@@ -119,6 +119,7 @@
     }
 
     oh_discard_local_handle(hThread);
+    hythread_exception_safe_point();
     tmn_suspend_disable();
 
     return true;

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp?view=diff&rev=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp Sat Mar 24 06:55:07 2007
@@ -53,8 +53,6 @@
 
     } else if (is_unwindable()) {
         // unwindable frame, wait for resume
-        TRACE(("PopFrame callback is entering safe_point"));
-        hythread_safe_point();
         TRACE(("PopFrame callback is FRAME_SAFE_POINT"));
 
         // switch execution to the previous frame
@@ -396,6 +394,10 @@
     Registers regs;
     M2nFrame* top_frame = m2n_get_last_frame();
     set_pop_frame_registers(top_frame, &regs);
+
+    TRACE(("entering exception_safe_point"));
+    hythread_exception_safe_point();
+    TRACE(("left exception_safe_point"));
 
     TRACE(("entering safe_point"));
     hythread_safe_point();

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp?view=diff&rev=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_step.cpp Sat Mar 24 06:55:07 2007
@@ -671,6 +671,7 @@
         jvmti_setup_jit_single_step(ti, m, location);
 
     oh_discard_local_handle(hThread);
+    hythread_exception_safe_point();
     tmn_suspend_disable();
 
     return true;

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_manager.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_manager.cpp?view=diff&rev=522033&r1=522032&r2=522033
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_manager.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/thread/thread_manager.cpp Sat Mar 24 06:55:07 2007
@@ -167,6 +167,8 @@
 
 IDATA jthread_throw_exception_object(jobject object) {
     if (interpreter_enabled()) {
+        // FIXME - Function set_current_thread_exception does the same
+        // actions as exn_raise_object, and it should be replaced.
         set_current_thread_exception(object->object);
     } else {
         if (is_unwindable()) {