diff --git a/vm/include/interpreter_exports.h b/vm/include/interpreter_exports.h index f6346c3..36bf168 100644 --- a/vm/include/interpreter_exports.h +++ b/vm/include/interpreter_exports.h @@ -61,20 +61,20 @@ typedef struct { * @param[out] stfs - the pointer to the array of stack trace frames * created by this function and returned via this pointer * @note The caller is responsible for freeing the memory.*/ - void (*interpreter_st_get_trace) (class VM_thread *thread, unsigned* res_depth, struct StackTraceFrame** stfs); + void (*interpreter_st_get_trace) (struct VM_thread *thread, unsigned* res_depth, struct StackTraceFrame** stfs); /** * Enumerates references associated with the thread. * * @param thread - the pointer to the thread*/ - void (*interpreter_enumerate_thread) (class VM_thread *thread); + void (*interpreter_enumerate_thread) (struct VM_thread *thread); /** * Returns the last frame. * * @param thread - the pointer to the thread * @return The pointer to the last frame.*/ - FrameHandle* (*interpreter_get_last_frame) (class VM_thread *thread); + FrameHandle* (*interpreter_get_last_frame) (struct VM_thread *thread); /** Returns the previous frame. * @@ -111,7 +111,7 @@ typedef struct { * * @param thread - the pointer to the thread * @param jvmtiEnv - the pointer to the jvmti environment*/ - void (*interpreter_ti_enumerate_thread) (jvmtiEnv*, class VM_thread *thread); + void (*interpreter_ti_enumerate_thread) (jvmtiEnv*, struct VM_thread *thread); #ifdef _IPF_ /** @@ -133,7 +133,7 @@ typedef struct { * @param jlocation - the pointer to the location * @return JVMTI_ERROR_NONE - a successfully added notification
* JVMTI_ERROR_NO_MORE_FRAMES - depth is too large*/ - jvmtiError (*interpreter_ti_getFrameLocation) ( jvmtiEnv*, class VM_thread*, + jvmtiError (*interpreter_ti_getFrameLocation) ( jvmtiEnv*, struct VM_thread*, int, struct _jmethodID * *, int64 *); /** @@ -149,7 +149,7 @@ typedef struct { * JVMTI_ERROR_OPAQUE_FRAME - no frame
* JVMTI_ERROR_INVALID_SLOT - a bad slot
* JVMTI_ERROR_TYPE_MISMATCH - an invalid variable type*/ - jvmtiError (*interpreter_ti_getLocal32) ( jvmtiEnv*, class VM_thread*, int, int, int *); + jvmtiError (*interpreter_ti_getLocal32) ( jvmtiEnv*, struct VM_thread*, int, int, int *); /** * Returns the value of 64 bit local variable. @@ -164,7 +164,7 @@ typedef struct { * JVMTI_ERROR_OPAQUE_FRAME - no frame
* JVMTI_ERROR_INVALID_SLOT - a bad slot
* JVMTI_ERROR_TYPE_MISMATCH - an invalid variable type*/ - jvmtiError (*interpreter_ti_getLocal64) ( jvmtiEnv*, class VM_thread*, int, int, int64 *); + jvmtiError (*interpreter_ti_getLocal64) ( jvmtiEnv*, struct VM_thread*, int, int, int64 *); /** * Returns the value of the Object type local variable. @@ -179,7 +179,7 @@ typedef struct { * JVMTI_ERROR_OPAQUE_FRAME - no frame
* JVMTI_ERROR_INVALID_SLOT - a bad slot
* JVMTI_ERROR_TYPE_MISMATCH - an invalid variable type*/ - jvmtiError (*interpreter_ti_getObject) ( jvmtiEnv*, class VM_thread*, int, int, struct _jobject * *); + jvmtiError (*interpreter_ti_getObject) ( jvmtiEnv*, struct VM_thread*, int, int, struct _jobject * *); /** * Returns stack trace data. @@ -192,7 +192,7 @@ typedef struct { * @param count_ptr - the pointer to the count * @return JVMTI_ERROR_NONE - a successfully added notification
* JVMTI_ERROR_ILLEGAL_ARGUMENT - bad arguments*/ - jvmtiError (*interpreter_ti_getStackTrace) (jvmtiEnv*, class VM_thread*, int, int, jvmtiFrameInfo*, int *); + jvmtiError (*interpreter_ti_getStackTrace) (jvmtiEnv*, struct VM_thread*, int, int, jvmtiFrameInfo*, int *); /** * Returns frame count. @@ -201,7 +201,7 @@ typedef struct { * @param thread - the pointer to the thread * @param count_ptr[out] - the pointer to the count * @return JVMTI_ERROR_NONE - a successfully added notification*/ - jvmtiError (*interpreter_ti_get_frame_count) ( jvmtiEnv*, class VM_thread*, int *); + jvmtiError (*interpreter_ti_get_frame_count) ( jvmtiEnv*, struct VM_thread*, int *); /** * Sets the value of 32 bit local variable. @@ -216,7 +216,7 @@ typedef struct { * JVMTI_ERROR_OPAQUE_FRAME - no frame
* JVMTI_ERROR_INVALID_SLOT - a bad slot
* JVMTI_ERROR_TYPE_MISMATCH - an invalid variable type*/ - jvmtiError (*interpreter_ti_setLocal32) ( jvmtiEnv*, class VM_thread*, int, int, int); + jvmtiError (*interpreter_ti_setLocal32) ( jvmtiEnv*, struct VM_thread*, int, int, int); /** * Sets the value of 64 bit local variable. @@ -231,7 +231,7 @@ typedef struct { * JVMTI_ERROR_OPAQUE_FRAME - no frame
* JVMTI_ERROR_INVALID_SLOT - a bad slot
* JVMTI_ERROR_TYPE_MISMATCH - an invalid variable type
*/ - jvmtiError (*interpreter_ti_setLocal64) ( jvmtiEnv*, class VM_thread*, int, int, int64); + jvmtiError (*interpreter_ti_setLocal64) ( jvmtiEnv*, struct VM_thread*, int, int, int64); /** * Sets the value of the Object type local variable. @@ -246,14 +246,14 @@ typedef struct { * JVMTI_ERROR_OPAQUE_FRAME - no frame
* JVMTI_ERROR_INVALID_SLOT - a bad slot
* JVMTI_ERROR_TYPE_MISMATCH - an invalid variable type*/ - jvmtiError (*interpreter_ti_setObject) ( jvmtiEnv*, class VM_thread*, int, int, struct _jobject *); + jvmtiError (*interpreter_ti_setObject) ( jvmtiEnv*, struct VM_thread*, int, int, struct _jobject *); /** * Returns the interrupted method native bit. * * @param thread - the pointer to the thread * @return The interrupted method native bit.*/ - unsigned int (*interpreter_st_get_interrupted_method_native_bit) (class VM_thread *); + unsigned int (*interpreter_st_get_interrupted_method_native_bit) (struct VM_thread *); /** @defgroup open_interfaces Open Interfaces * Open interfaces.*/ diff --git a/vm/include/jvmti_support.h b/vm/include/jvmti_support.h index afdae1f..551b3fb 100644 --- a/vm/include/jvmti_support.h +++ b/vm/include/jvmti_support.h @@ -51,12 +51,12 @@ VMEXPORT void vm_ti_enumerate_heap_root(jvmtiEnv* env, /** * Requests interpreter to enumerate one thread for TI. */ -void interpreter_ti_enumerate_thread(jvmtiEnv *env, class VM_thread *thread); +void interpreter_ti_enumerate_thread(jvmtiEnv *env, struct VM_thread *thread); /** * Requests JIT support to enumerate one thread for TI. */ -void jitted_ti_enumerate_thread(jvmtiEnv *env, class VM_thread *thread); +void jitted_ti_enumerate_thread(jvmtiEnv *env, struct VM_thread *thread); #endif // _JVMTI_SUPPORT_H_ diff --git a/vm/include/open/hythread.h b/vm/include/open/hythread.h index 89e533c..d528942 100644 --- a/vm/include/open/hythread.h +++ b/vm/include/open/hythread.h @@ -348,7 +348,7 @@ typedef struct HyThread_public { * for current thread only. * * Also disable_count could be reset to value 0 and restored in - * reset_suspend_disable()/set_suspend_disable() function + * hythread_reset_suspend_disable()/hythread_set_suspend_disable() function * for current thread only. * * Function hythread_exception_safe_point() sets disable_count to diff --git a/vm/include/open/hythread_ext.h b/vm/include/open/hythread_ext.h index 2015935..e9422a3 100644 --- a/vm/include/open/hythread_ext.h +++ b/vm/include/open/hythread_ext.h @@ -153,13 +153,17 @@ extern "C" { #include "hycond_win.h" #endif // _WIN32 +#if !defined (_IPF_) +//use lock reservation +#define LOCK_RESERVATION +#endif // !defined (_IPF_) typedef struct HyLatch *hylatch_t; typedef struct HyThread *hythread_iterator_t; typedef struct HyThreadLibrary *hythread_library_t; -typedef I_32 hythread_thin_monitor_t; +typedef U_32 hythread_thin_monitor_t; typedef void (*hythread_event_callback_proc)(void); @@ -210,6 +214,22 @@ UDATA hythread_get_thread_stacksize(hythread_t thread); UDATA VMCALL hythread_uses_fast_tls(void); IDATA VMCALL hythread_get_hythread_offset_in_tls(void); +IDATA VMCALL hythread_thread_lock(hythread_t thread); +IDATA VMCALL hythread_thread_unlock(hythread_t thread); +IDATA VMCALL hythread_get_state(hythread_t thread); +IDATA VMCALL hythread_set_state(hythread_t thread, IDATA state); +int VMCALL hythread_reset_suspend_disable(); +void VMCALL hythread_set_suspend_disable(int count); +int VMCALL hythread_is_fat_lock(hythread_thin_monitor_t lockword); +hythread_monitor_t VMCALL hythread_inflate_lock(hythread_thin_monitor_t *lockword_ptr); +IDATA VMCALL hythread_owns_thin_lock(hythread_t thread, hythread_thin_monitor_t lockword); +IDATA VMCALL hythread_unreserve_lock(hythread_thin_monitor_t *lockword_ptr); +IDATA VMCALL hythread_get_thread_id_offset(); +IDATA VMCALL hythread_set_thread_stop_callback(hythread_t thread, hythread_event_callback_proc stop_callback); +IDATA VMCALL hythread_wait_for_nondaemon_threads(hythread_t thread, IDATA threads_to_keep); +IDATA VMCALL hythread_increase_nondaemon_threads_count(hythread_t thread); +IDATA VMCALL hythread_decrease_nondaemon_threads_count(hythread_t thread, IDATA threads_to_keep); + //@} /** @name Conditional variable */ @@ -489,7 +509,11 @@ hy_inline void VMCALL hythread_suspend_disable() // possible values for tm_status_t #define TM_OS_ERROR (TM_ERROR_START+1) - + +#define TM_MAX_OWNED_MONITOR_NUMBER 200 //FIXME: switch to dynamic resize +// if default stack size is not through -Xss parameter, it is 256kb +#define TM_DEFAULT_STACKSIZE (512 * 1024) + #if defined(__cplusplus) } #endif diff --git a/vm/include/open/jthread.h b/vm/include/open/jthread.h index bb17f17..dd35bb5 100644 --- a/vm/include/open/jthread.h +++ b/vm/include/open/jthread.h @@ -35,52 +35,25 @@ * vm/thread/doc/ThreadManager.htm */ -#include "open/types.h" -#include "open/hythread_ext.h" #include #include +#include "open/types.h" +#include "open/hythread_ext.h" +#include "open/ti_thread.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ - /** * @name Basic manipulation */ //@{ typedef struct JVMTIThread *jvmti_thread_t; +typedef struct jthread_thread_attr jthread_threadattr_t; -/** - * Java thread creation attributes. - */ -typedef struct { - - /** - * Thread scheduling priority. - */ - jint priority; - - /** - * Thread stack size. - */ - jint stacksize; - - /** - * Denotes whether Java thread is daemon. - * JVM exits when the only threads running are daemon threads. - */ - jboolean daemon; - - /** - * JVM TI Environment. - */ - jvmtiEnv * jvmti_env; - -} jthread_threadattr_t; - -VMEXPORT jlong jthread_thread_init(jvmti_thread_t *ret_thread, JNIEnv* env, jthread java_thread, jobject weak_ref, jlong old_thread); +VMEXPORT jlong jthread_thread_init(JNIEnv* env, jthread java_thread, jobject weak_ref, hythread_t old_thread); VMEXPORT IDATA jthread_create(JNIEnv * jni_env, jthread thread, jthread_threadattr_t *attrs); VMEXPORT IDATA jthread_create_with_function(JNIEnv * jni_env, jthread thread, jthread_threadattr_t *attrs, jvmtiStartFunction proc, const void* arg); VMEXPORT IDATA jthread_attach(JNIEnv * jni_env, jthread thread, jboolean daemon); diff --git a/vm/include/open/ti_thread.h b/vm/include/open/ti_thread.h index 12052a4..06ecb62 100644 --- a/vm/include/open/ti_thread.h +++ b/vm/include/open/ti_thread.h @@ -52,7 +52,7 @@ typedef struct HyThread *jthread_iterator_t; */ //@{ -VMEXPORT IDATA jthread_get_state(jthread thread, jint *thread_state); +VMEXPORT IDATA jthread_get_jvmti_state(jthread thread, jint *thread_state); //@} /** @name Instrumentation diff --git a/vm/interpreter/src/interp_exports.cpp b/vm/interpreter/src/interp_exports.cpp index 21d5ef3..3be1f79 100644 --- a/vm/interpreter/src/interp_exports.cpp +++ b/vm/interpreter/src/interp_exports.cpp @@ -66,21 +66,21 @@ struct StackTraceFrame; extern bool interpreter_st_get_frame(unsigned target_depth, StackTraceFrame* stf); extern jvmtiError interpreter_ti_getFrameLocation( - struct jvmtiEnv_struct *,class VM_thread *,int, struct _jmethodID * *,int64 *); -extern jvmtiError interpreter_ti_getLocal32( struct jvmtiEnv_struct *,class VM_thread *,int,int,int *); -extern jvmtiError interpreter_ti_getLocal64( struct jvmtiEnv_struct *,class VM_thread *,int,int,int64 *); -extern jvmtiError interpreter_ti_getObject( struct jvmtiEnv_struct *,class VM_thread *,int,int,struct _jobject * *); -extern jvmtiError interpreter_ti_getStackTrace(struct jvmtiEnv_struct *,class VM_thread *,int,int,jvmtiFrameInfo *,int *); + struct jvmtiEnv_struct *,struct VM_thread *,int, struct _jmethodID * *,int64 *); +extern jvmtiError interpreter_ti_getLocal32( struct jvmtiEnv_struct *,struct VM_thread *,int,int,int *); +extern jvmtiError interpreter_ti_getLocal64( struct jvmtiEnv_struct *,struct VM_thread *,int,int,int64 *); +extern jvmtiError interpreter_ti_getObject( struct jvmtiEnv_struct *,struct VM_thread *,int,int,struct _jobject * *); +extern jvmtiError interpreter_ti_getStackTrace(struct jvmtiEnv_struct *,struct VM_thread *,int,int,jvmtiFrameInfo *,int *); -extern jvmtiError interpreter_ti_get_frame_count( struct jvmtiEnv_struct *,class VM_thread *,int *); +extern jvmtiError interpreter_ti_get_frame_count( struct jvmtiEnv_struct *,struct VM_thread *,int *); extern jvmtiError interpreter_ti_notify_frame_pop (jvmtiEnv*, VM_thread *thread, int depth); -extern jvmtiError interpreter_ti_setLocal32( struct jvmtiEnv_struct *,class VM_thread *,int,int,int); -extern jvmtiError interpreter_ti_setLocal64( struct jvmtiEnv_struct *,class VM_thread *,int,int,int64); -extern jvmtiError interpreter_ti_setObject( struct jvmtiEnv_struct *,class VM_thread *,int,int,struct _jobject *); +extern jvmtiError interpreter_ti_setLocal32( struct jvmtiEnv_struct *,struct VM_thread *,int,int,int); +extern jvmtiError interpreter_ti_setLocal64( struct jvmtiEnv_struct *,struct VM_thread *,int,int,int64); +extern jvmtiError interpreter_ti_setObject( struct jvmtiEnv_struct *,struct VM_thread *,int,int,struct _jobject *); -extern unsigned int interpreter_st_get_interrupted_method_native_bit(class VM_thread *); -extern void interpreter_enumerate_thread(class VM_thread *); -extern void interpreter_ti_enumerate_thread(jvmtiEnv*, class VM_thread*); +extern unsigned int interpreter_st_get_interrupted_method_native_bit(struct VM_thread *); +extern void interpreter_enumerate_thread(struct VM_thread *); +extern void interpreter_ti_enumerate_thread(jvmtiEnv*, struct VM_thread*); extern void interpreter_st_get_interrupted_method(struct Method * *,int64 *); extern void interpreter_st_get_catch_method(struct Method * *,int64 *,struct _jobject *); extern void interpreter_st_get_trace(VM_thread *thread, unsigned int *,struct StackTraceFrame * *); @@ -93,7 +93,7 @@ extern void interpreter_ti_clear_breakpoint(jmethodID method, jlocation location extern jvmtiError interpreter_ti_pop_frame(jvmtiEnv*, VM_thread *thread); extern void stack_dump(int fd, VM_thread *thread); -extern FrameHandle* interpreter_get_last_frame(class VM_thread *thread); +extern FrameHandle* interpreter_get_last_frame(struct VM_thread *thread); extern FrameHandle* interpreter_get_prev_frame(FrameHandle* frame); extern Method_Handle interpreter_get_frame_method(FrameHandle* frame); extern uint8* interpreter_get_frame_bytecode_ptr(FrameHandle* frame); diff --git a/vm/interpreter/src/interpreter_ti.cpp b/vm/interpreter/src/interpreter_ti.cpp index e4b8ded..44fd38c 100644 --- a/vm/interpreter/src/interpreter_ti.cpp +++ b/vm/interpreter/src/interpreter_ti.cpp @@ -506,7 +506,7 @@ void single_step_callback(StackFrame &frame) { //////////////////////////////////////// // Interpreter frames iteration -FrameHandle* interpreter_get_last_frame(class VM_thread *thread) +FrameHandle* interpreter_get_last_frame(struct VM_thread *thread) { return (FrameHandle*)getLastStackFrame(thread); } diff --git a/vm/port/src/lil/em64t/pim/m2n_em64t.cpp b/vm/port/src/lil/em64t/pim/m2n_em64t.cpp index 8b5a316..1f8b007 100644 --- a/vm/port/src/lil/em64t/pim/m2n_em64t.cpp +++ b/vm/port/src/lil/em64t/pim/m2n_em64t.cpp @@ -42,11 +42,11 @@ void m2n_null_init(M2nFrame * m2n){ } M2nFrame* m2n_get_last_frame() { - return p_TLS_vmthread->last_m2n_frame; + return (M2nFrame*)p_TLS_vmthread->last_m2n_frame; } M2nFrame* m2n_get_last_frame(VM_thread * thread) { - return thread->last_m2n_frame; + return (M2nFrame*)thread->last_m2n_frame; } void m2n_set_last_frame(VM_thread* thread, M2nFrame * lm2nf) { diff --git a/vm/port/src/lil/ia32/pim/m2n_ia32.cpp b/vm/port/src/lil/ia32/pim/m2n_ia32.cpp index c6c85af..5cd3a6f 100644 --- a/vm/port/src/lil/ia32/pim/m2n_ia32.cpp +++ b/vm/port/src/lil/ia32/pim/m2n_ia32.cpp @@ -45,13 +45,13 @@ void m2n_null_init(M2nFrame* m2n){ VMEXPORT // temporary solution for interpreter unplug M2nFrame* m2n_get_last_frame() { - return p_TLS_vmthread->last_m2n_frame; + return (M2nFrame*)p_TLS_vmthread->last_m2n_frame; } VMEXPORT // temporary solution for interpreter unplug M2nFrame* m2n_get_last_frame(VM_thread* thread) { - return thread->last_m2n_frame; + return (M2nFrame*)thread->last_m2n_frame; } VMEXPORT // temporary solution for interpreter unplug diff --git a/vm/port/src/lil/ipf/pim/m2n_ipf.cpp b/vm/port/src/lil/ipf/pim/m2n_ipf.cpp index 95f58da..afc41b6 100644 --- a/vm/port/src/lil/ipf/pim/m2n_ipf.cpp +++ b/vm/port/src/lil/ipf/pim/m2n_ipf.cpp @@ -90,13 +90,13 @@ void m2n_null_init(M2nFrame* m2n){ VMEXPORT // temporary solution for interpreter unplug M2nFrame* m2n_get_last_frame() { - return p_TLS_vmthread->last_m2n_frame; + return (M2nFrame*)p_TLS_vmthread->last_m2n_frame; } VMEXPORT // temporary solution for interpreter unplug M2nFrame* m2n_get_last_frame(VM_thread* thread) { - return thread->last_m2n_frame; + return (M2nFrame*)thread->last_m2n_frame; } VMEXPORT // temporary solution for interpreter unplug diff --git a/vm/tests/unit/thread/test_java_basic.c b/vm/tests/unit/thread/test_java_basic.c index 8071afc..ab42c40 100644 --- a/vm/tests/unit/thread/test_java_basic.c +++ b/vm/tests/unit/thread/test_java_basic.c @@ -20,7 +20,7 @@ #include "thread_unit_test_utils.h" #include #include -#include "thread_private.h" +#include "thread_manager.h" /* * Time for jthread_timed_join() to wait diff --git a/vm/tests/unit/thread/test_java_identify.c b/vm/tests/unit/thread/test_java_identify.c index 44af76e..fe40ca0 100644 --- a/vm/tests/unit/thread/test_java_identify.c +++ b/vm/tests/unit/thread/test_java_identify.c @@ -20,7 +20,7 @@ #include "thread_unit_test_utils.h" #include #include -#include "thread_private.h" +#include "thread_manager.h" /* diff --git a/vm/tests/unit/thread/test_java_ptr_conv.c b/vm/tests/unit/thread/test_java_ptr_conv.c index 359d0fd..4fc8095 100644 --- a/vm/tests/unit/thread/test_java_ptr_conv.c +++ b/vm/tests/unit/thread/test_java_ptr_conv.c @@ -20,7 +20,7 @@ #include "thread_unit_test_utils.h" #include #include -#include "thread_private.h" +#include "thread_manager.h" /* diff --git a/vm/tests/unit/thread/test_native_basic.c b/vm/tests/unit/thread/test_native_basic.c index dfdc92a..cc7db45 100644 --- a/vm/tests/unit/thread/test_native_basic.c +++ b/vm/tests/unit/thread/test_native_basic.c @@ -16,12 +16,11 @@ */ #include -#include "thread_private.h" #include #include -#include "testframe.h" -#include "jthread.h" #include +#include "testframe.h" +#include "thread_manager.h" int start_proc(void *); int start_proc_empty(void *); @@ -223,15 +222,15 @@ int test_hythread_create_many(void){ //1.group //// tf_assert(group); - tf_assert(group->threads_count == 0); + //tf_assert(group->threads_count == 0); return 0; } int start_proc(void *args) { void** attrs = (void **)args; - tf_assert_same(hythread_self()->priority, ((jthread_threadattr_t *)attrs[1])->priority); - tf_assert_same(hythread_self()->group, attrs[0]); + tf_assert_same(hythread_get_priority(hythread_self()), ((jthread_threadattr_t *)attrs[1])->priority); + tf_assert_same(((HyThread_public*)hythread_self())->group, attrs[0]); return 0; } diff --git a/vm/tests/unit/thread/test_native_fat_monitor.c b/vm/tests/unit/thread/test_native_fat_monitor.c index 0fa29fa..1923407 100644 --- a/vm/tests/unit/thread/test_native_fat_monitor.c +++ b/vm/tests/unit/thread/test_native_fat_monitor.c @@ -15,7 +15,7 @@ * limitations under the License. */ -#include "thread_private.h" +#include "thread_manager.h" #include "testframe.h" #include "open/jthread.h" #include diff --git a/vm/tests/unit/thread/test_native_suspend.c b/vm/tests/unit/thread/test_native_suspend.c index 2c9c6b4..0137c6d 100644 --- a/vm/tests/unit/thread/test_native_suspend.c +++ b/vm/tests/unit/thread/test_native_suspend.c @@ -16,12 +16,11 @@ */ #include -#include "thread_private.h" #include #include -#include "testframe.h" #include -#include "open/jthread.h" +#include "testframe.h" +#include "thread_manager.h" int start_proc(void *); @@ -91,7 +90,7 @@ int test_hythread_thread_suspend_all(void){ hythread_create(&thread, 0, 0, 0, start_proc, args); } hythread_sleep(500); - hythread_suspend_all(NULL, hythread_self()->group); + hythread_suspend_all(NULL, ((HyThread_public*)hythread_self())->group); hythread_suspend_disable(); status = hythread_thin_monitor_enter(lockword_ptr); tf_assert_same(status, TM_ERROR_NONE); @@ -107,7 +106,7 @@ int test_hythread_thread_suspend_all(void){ tf_assert_same(args[1], 0); } - hythread_resume_all(hythread_self()->group); + hythread_resume_all(((HyThread_public*)hythread_self())->group); hythread_join(thread); diff --git a/vm/tests/unit/thread/test_native_thin_monitor.c b/vm/tests/unit/thread/test_native_thin_monitor.c index 3817563..1cadbfe 100644 --- a/vm/tests/unit/thread/test_native_thin_monitor.c +++ b/vm/tests/unit/thread/test_native_thin_monitor.c @@ -16,11 +16,9 @@ */ #include -#include "thread_private.h" #include #include #include "testframe.h" -#include "jthread.h" #include int start_proc(void *); diff --git a/vm/tests/unit/thread/test_ti_state.c b/vm/tests/unit/thread/test_ti_state.c index f8a21e2..e019d02 100644 --- a/vm/tests/unit/thread/test_ti_state.c +++ b/vm/tests/unit/thread/test_ti_state.c @@ -24,7 +24,7 @@ #include /* - * Test jthread_get_state(...) + * Test jthread_get_jvmti_state(...) * * called function tested state * @@ -34,7 +34,7 @@ * jthread_clear_interrupted() ALIVE | RUNNABLE * DEAD */ -void JNICALL run_for_test_jthread_get_state_1(jvmtiEnv * jvmti_env, JNIEnv * jni_env, void *args){ +void JNICALL run_for_test_jthread_get_jvmti_state_1(jvmtiEnv * jvmti_env, JNIEnv * jni_env, void *args){ tested_thread_sturct_t * tts = (tested_thread_sturct_t *) args; @@ -48,7 +48,7 @@ void JNICALL run_for_test_jthread_get_state_1(jvmtiEnv * jvmti_env, JNIEnv * jni tested_thread_ended(tts); } -int test_jthread_get_state_1(void) { +int test_jthread_get_jvmti_state_1(void) { tested_thread_sturct_t *tts; int state; @@ -59,7 +59,7 @@ int test_jthread_get_state_1(void) { reset_tested_thread_iterator(&tts); while(next_tested_thread(&tts)){ - tf_assert_same(jthread_get_state(tts->java_thread, &state), TM_ERROR_NONE); + tf_assert_same(jthread_get_jvmti_state(tts->java_thread, &state), TM_ERROR_NONE); ref_state = 0; if(tts->my_index == 0){ printf("state = %08x (%08x)\n", state, ref_state); @@ -68,12 +68,12 @@ int test_jthread_get_state_1(void) { } // Run all tested threads - tested_threads_run_common(run_for_test_jthread_get_state_1); + tested_threads_run_common(run_for_test_jthread_get_jvmti_state_1); reset_tested_thread_iterator(&tts); while(next_tested_thread(&tts)){ tested_thread_wait_running(tts); - tf_assert_same(jthread_get_state(tts->java_thread, &state), TM_ERROR_NONE); + tf_assert_same(jthread_get_jvmti_state(tts->java_thread, &state), TM_ERROR_NONE); ref_state = 0x5; if(tts->my_index == 0){ printf("state = %08x (%08x)\n", state, ref_state); @@ -81,7 +81,7 @@ int test_jthread_get_state_1(void) { //tf_assert_same(state, ref_state); tf_assert_same(jthread_interrupt(tts->java_thread), TM_ERROR_NONE); - tf_assert_same(jthread_get_state(tts->java_thread, &state), TM_ERROR_NONE); + tf_assert_same(jthread_get_jvmti_state(tts->java_thread, &state), TM_ERROR_NONE); ref_state = 0x200005; if(tts->my_index == 0){ printf("state = %08x (%08x)\n", state, ref_state); @@ -89,7 +89,7 @@ int test_jthread_get_state_1(void) { //tf_assert_same(state, ref_state); tf_assert_same(jthread_clear_interrupted(tts->java_thread), TM_ERROR_INTERRUPT); - tf_assert_same(jthread_get_state(tts->java_thread, &state), TM_ERROR_NONE); + tf_assert_same(jthread_get_jvmti_state(tts->java_thread, &state), TM_ERROR_NONE); ref_state = 0x5; if(tts->my_index == 0){ printf("state = %08x (%08x)\n", state, ref_state); @@ -99,7 +99,7 @@ int test_jthread_get_state_1(void) { tested_thread_send_stop_request(tts); tested_thread_wait_ended(tts); check_tested_thread_phase(tts, TT_PHASE_DEAD); - tf_assert_same(jthread_get_state(tts->java_thread, &state), TM_ERROR_NONE); + tf_assert_same(jthread_get_jvmti_state(tts->java_thread, &state), TM_ERROR_NONE); ref_state = 0x2; if(tts->my_index == 0){ printf("state = %08x (%08x)\n", state, ref_state); @@ -113,9 +113,9 @@ int test_jthread_get_state_1(void) { return TEST_PASSED; } /* - * Test jthread_get_state(...) + * Test jthread_get_jvmti_state(...) */ -void JNICALL run_for_test_jthread_get_state_2(jvmtiEnv * jvmti_env, JNIEnv * jni_env, void *args){ +void JNICALL run_for_test_jthread_get_jvmti_state_2(jvmtiEnv * jvmti_env, JNIEnv * jni_env, void *args){ tested_thread_sturct_t * tts = (tested_thread_sturct_t *) args; jobject monitor = tts->monitor; @@ -147,7 +147,7 @@ void JNICALL run_for_test_jthread_get_state_2(jvmtiEnv * jvmti_env, JNIEnv * jni tested_thread_ended(tts); } -int test_jthread_get_state_2(void) { +int test_jthread_get_jvmti_state_2(void) { tested_thread_sturct_t *tts; jobject monitor; @@ -165,12 +165,12 @@ int test_jthread_get_state_2(void) { status = jthread_monitor_enter(monitor); // Run all tested threads - tested_threads_run_common(run_for_test_jthread_get_state_2); + tested_threads_run_common(run_for_test_jthread_get_jvmti_state_2); reset_tested_thread_iterator(&tts); while(next_tested_thread(&tts)){ check_tested_thread_phase(tts, TT_PHASE_WAITING_ON_MONITOR); - tf_assert_same(jthread_get_state(tts->java_thread, &state), TM_ERROR_NONE); + tf_assert_same(jthread_get_jvmti_state(tts->java_thread, &state), TM_ERROR_NONE); ref_state = 0x401; if(tts->my_index == 0){ printf("state = %08x (%08x)\n", state, ref_state); @@ -183,7 +183,7 @@ int test_jthread_get_state_2(void) { reset_tested_thread_iterator(&tts); while(next_tested_thread(&tts)){ check_tested_thread_phase(tts, TT_PHASE_WAITING_ON_WAIT); - tf_assert_same(jthread_get_state(tts->java_thread, &state), TM_ERROR_NONE); + tf_assert_same(jthread_get_jvmti_state(tts->java_thread, &state), TM_ERROR_NONE); ref_state = 0x191; if(tts->my_index == 0){ printf("state = %08x (%08x)\n", state, ref_state); @@ -198,7 +198,7 @@ int test_jthread_get_state_2(void) { reset_tested_thread_iterator(&tts); while(next_tested_thread(&tts)){ check_tested_thread_phase(tts, TT_PHASE_WAITING_ON_WAIT); - tf_assert_same(jthread_get_state(tts->java_thread, &state), TM_ERROR_NONE); + tf_assert_same(jthread_get_jvmti_state(tts->java_thread, &state), TM_ERROR_NONE); ref_state = 0x401; if(tts->my_index == 0){ printf("state = %08x (%08x)\n", state, ref_state); @@ -212,7 +212,7 @@ int test_jthread_get_state_2(void) { reset_tested_thread_iterator(&tts); while(next_tested_thread(&tts)){ check_tested_thread_phase(tts, TT_PHASE_RUNNING); - tf_assert_same(jthread_get_state(tts->java_thread, &state), TM_ERROR_NONE); + tf_assert_same(jthread_get_jvmti_state(tts->java_thread, &state), TM_ERROR_NONE); ref_state = 0x5; if(tts->my_index == 0){ printf("state = %08x (%08x)\n", state, ref_state); @@ -227,9 +227,9 @@ int test_jthread_get_state_2(void) { } /* - * Test jthread_get_state(...) + * Test jthread_get_jvmti_state(...) */ -void JNICALL run_for_test_jthread_get_state_3(jvmtiEnv * jvmti_env, JNIEnv * jni_env, void *args){ +void JNICALL run_for_test_jthread_get_jvmti_state_3(jvmtiEnv * jvmti_env, JNIEnv * jni_env, void *args){ tested_thread_sturct_t * tts = (tested_thread_sturct_t *) args; jobject monitor = tts->monitor; @@ -257,25 +257,25 @@ void JNICALL run_for_test_jthread_get_state_3(jvmtiEnv * jvmti_env, JNIEnv * jni tested_thread_ended(tts); } -int test_jthread_get_state_3(void) { +int test_jthread_get_jvmti_state_3(void) { tested_thread_sturct_t *tts; int state; int ref_state; // Initialize tts structures and run all tested threads - tested_threads_run(run_for_test_jthread_get_state_3); + tested_threads_run(run_for_test_jthread_get_jvmti_state_3); reset_tested_thread_iterator(&tts); while(next_tested_thread(&tts)){ check_tested_thread_phase(tts, TT_PHASE_WAITING_ON_WAIT); - tf_assert_same(jthread_get_state(tts->java_thread, &state), TM_ERROR_NONE); + tf_assert_same(jthread_get_jvmti_state(tts->java_thread, &state), TM_ERROR_NONE); ref_state = 0x1a1; printf("state = %08x (%08x)\n", state, ref_state); //tf_assert_same(state, ref_state); tf_assert_same(jthread_interrupt(tts->java_thread), TM_ERROR_NONE); check_tested_thread_phase(tts, TT_PHASE_DEAD); - tf_assert_same(jthread_get_state(tts->java_thread, &state), TM_ERROR_NONE); + tf_assert_same(jthread_get_jvmti_state(tts->java_thread, &state), TM_ERROR_NONE); ref_state = 0x2; printf("state = %08x (%08x)\n", state, ref_state); //tf_assert_same(state, ref_state); @@ -288,9 +288,9 @@ int test_jthread_get_state_3(void) { } /* - * Test jthread_get_state(...) + * Test jthread_get_jvmti_state(...) */ -void JNICALL run_for_test_jthread_get_state_4(jvmtiEnv * jvmti_env, JNIEnv * jni_env, void *args){ +void JNICALL run_for_test_jthread_get_jvmti_state_4(jvmtiEnv * jvmti_env, JNIEnv * jni_env, void *args){ tested_thread_sturct_t * tts = (tested_thread_sturct_t *) args; jobject monitor = tts->monitor; @@ -318,14 +318,14 @@ void JNICALL run_for_test_jthread_get_state_4(jvmtiEnv * jvmti_env, JNIEnv * jni tested_thread_ended(tts); } -int test_jthread_get_state_4(void) { +int test_jthread_get_jvmti_state_4(void) { tested_thread_sturct_t *tts; int state; int ref_state; // Initialize tts structures and run all tested threads - tested_threads_run(run_for_test_jthread_get_state_4); + tested_threads_run(run_for_test_jthread_get_jvmti_state_4); // Wait for all threads wait timeout jthread_sleep(20 * CLICK_TIME_MSEC * MAX_TESTED_THREAD_NUMBER, 0); @@ -333,7 +333,7 @@ int test_jthread_get_state_4(void) { reset_tested_thread_iterator(&tts); while(next_tested_thread(&tts)){ check_tested_thread_phase(tts, TT_PHASE_DEAD); - tf_assert_same(jthread_get_state(tts->java_thread, &state), TM_ERROR_NONE); + tf_assert_same(jthread_get_jvmti_state(tts->java_thread, &state), TM_ERROR_NONE); ref_state = 0x2; printf("state = %08x (%08x)\n", state, ref_state); //tf_assert_same(state, ref_state); @@ -346,9 +346,9 @@ int test_jthread_get_state_4(void) { } /* - * Test jthread_get_state(...) + * Test jthread_get_jvmti_state(...) */ -void JNICALL run_for_test_jthread_get_state_5(jvmtiEnv * jvmti_env, JNIEnv * jni_env, void *args){ +void JNICALL run_for_test_jthread_get_jvmti_state_5(jvmtiEnv * jvmti_env, JNIEnv * jni_env, void *args){ tested_thread_sturct_t * tts = (tested_thread_sturct_t *) args; IDATA status; @@ -360,25 +360,25 @@ void JNICALL run_for_test_jthread_get_state_5(jvmtiEnv * jvmti_env, JNIEnv * jni tested_thread_ended(tts); } -int test_jthread_get_state_5(void) { +int test_jthread_get_jvmti_state_5(void) { tested_thread_sturct_t *tts; int state; int ref_state; // Initialize tts structures and run all tested threads - tested_threads_run(run_for_test_jthread_get_state_5); + tested_threads_run(run_for_test_jthread_get_jvmti_state_5); reset_tested_thread_iterator(&tts); while(next_tested_thread(&tts)){ check_tested_thread_phase(tts, TT_PHASE_SLEEPING); - tf_assert_same(jthread_get_state(tts->java_thread, &state), TM_ERROR_NONE); + tf_assert_same(jthread_get_jvmti_state(tts->java_thread, &state), TM_ERROR_NONE); ref_state = 0; printf("state = %08x (%08x)\n", state, ref_state); //tf_assert_same(state, ref_state); tf_assert_same(jthread_interrupt(tts->java_thread), TM_ERROR_NONE); check_tested_thread_phase(tts, TT_PHASE_DEAD); - tf_assert_same(jthread_get_state(tts->java_thread, &state), TM_ERROR_NONE); + tf_assert_same(jthread_get_jvmti_state(tts->java_thread, &state), TM_ERROR_NONE); ref_state = 0; printf("state = %08x (%08x)\n", state, ref_state); //tf_assert_same(state, ref_state); @@ -391,9 +391,9 @@ int test_jthread_get_state_5(void) { } /* - * Test jthread_get_state(...) + * Test jthread_get_jvmti_state(...) */ -void JNICALL run_for_test_jthread_get_state_6(jvmtiEnv * jvmti_env, JNIEnv * jni_env, void *args){ +void JNICALL run_for_test_jthread_get_jvmti_state_6(jvmtiEnv * jvmti_env, JNIEnv * jni_env, void *args){ tested_thread_sturct_t * tts = (tested_thread_sturct_t *) args; IDATA status; @@ -405,14 +405,14 @@ void JNICALL run_for_test_jthread_get_state_6(jvmtiEnv * jvmti_env, JNIEnv * jni tested_thread_ended(tts); } -int test_jthread_get_state_6(void) { +int test_jthread_get_jvmti_state_6(void) { tested_thread_sturct_t *tts; int state; int ref_state; // Initialize tts structures and run all tested threads - tested_threads_run(run_for_test_jthread_get_state_6); + tested_threads_run(run_for_test_jthread_get_jvmti_state_6); // Wait for all threads wait timeout jthread_sleep(20 * CLICK_TIME_MSEC * MAX_TESTED_THREAD_NUMBER, 0); @@ -420,7 +420,7 @@ int test_jthread_get_state_6(void) { reset_tested_thread_iterator(&tts); while(next_tested_thread(&tts)){ check_tested_thread_phase(tts, TT_PHASE_DEAD); - tf_assert_same(jthread_get_state(tts->java_thread, &state), TM_ERROR_NONE); + tf_assert_same(jthread_get_jvmti_state(tts->java_thread, &state), TM_ERROR_NONE); ref_state = 0x2; printf("state = %08x (%08x)\n", state, ref_state); //tf_assert_same(state, ref_state); @@ -433,10 +433,10 @@ int test_jthread_get_state_6(void) { } TEST_LIST_START - //TEST(test_jthread_get_state_1) - //TEST(test_jthread_get_state_2) - //TEST(test_jthread_get_state_3) - //TEST(test_jthread_get_state_4) - //TEST(test_jthread_get_state_5) - TEST(test_jthread_get_state_6) + //TEST(test_jthread_get_jvmti_state_1) + //TEST(test_jthread_get_jvmti_state_2) + //TEST(test_jthread_get_jvmti_state_3) + //TEST(test_jthread_get_jvmti_state_4) + //TEST(test_jthread_get_jvmti_state_5) + TEST(test_jthread_get_jvmti_state_6) TEST_LIST_END; diff --git a/vm/tests/unit/thread/utils/thread_unit_test_utils.h b/vm/tests/unit/thread/utils/thread_unit_test_utils.h index 9e9b818..df38e78 100644 --- a/vm/tests/unit/thread/utils/thread_unit_test_utils.h +++ b/vm/tests/unit/thread/utils/thread_unit_test_utils.h @@ -19,6 +19,7 @@ #include "apr_thread_proc.h" #include "open/hycomp.h" #include "open/jthread.h" +#include "thread_manager.h" // Tested Thread Phases #define TT_PHASE_NONE 0 diff --git a/vm/thread/src/hythr.def b/vm/thread/src/hythr.def index d35db35..aa434ba 100644 --- a/vm/thread/src/hythr.def +++ b/vm/thread/src/hythr.def @@ -133,14 +133,12 @@ hythread_lib_destroy hythread_lib_lock hythread_lib_unlock -release_start_lock -acquire_start_lock -inflate_lock -is_fat_lock -owns_thin_lock -unreserve_lock -set_suspend_disable -reset_suspend_disable +hythread_inflate_lock +hythread_is_fat_lock +hythread_owns_thin_lock +hythread_unreserve_lock +hythread_set_suspend_disable +hythread_reset_suspend_disable hythread_is_blocked_on_monitor_enter hythread_is_waiting hythread_is_in_native @@ -153,11 +151,15 @@ hythread_is_waiting_indefinitely hythread_is_runnable hythread_thin_monitor_get_recursion hythread_exit -array_add -array_create -array_delete -array_get get_java_thread_group +tm_properties -tm_properties; -Java_org_apache_harmony_drlvm_thread_ThreadHelper_getThreadIdOffset +hythread_thread_lock +hythread_thread_unlock +hythread_get_state +hythread_set_state +hythread_get_thread_id_offset +hythread_set_thread_stop_callback +hythread_wait_for_nondaemon_threads +hythread_increase_nondaemon_threads_count +hythread_decrease_nondaemon_threads_count diff --git a/vm/thread/src/hythr.exp b/vm/thread/src/hythr.exp index b1aec40..e47dfba 100644 --- a/vm/thread/src/hythr.exp +++ b/vm/thread/src/hythr.exp @@ -143,14 +143,12 @@ hythread_lib_lock; hythread_lib_unlock; set_safepoint_callback; -release_start_lock; -acquire_start_lock; -inflate_lock; -is_fat_lock; -owns_thin_lock; -unreserve_lock; -set_suspend_disable; -reset_suspend_disable; +hythread_inflate_lock; +hythread_is_fat_lock; +hythread_owns_thin_lock; +hythread_unreserve_lock; +hythread_set_suspend_disable; +hythread_reset_suspend_disable; hythread_is_blocked_on_monitor_enter; hythread_is_waiting; hythread_is_in_native; @@ -163,14 +161,18 @@ hythread_is_waiting_indefinitely; hythread_is_runnable; hythread_is_terminated; hythread_thin_monitor_get_recursion; -array_add; -array_create; -array_delete; -array_get; get_java_thread_group; tm_properties; -Java_org_apache_harmony_drlvm_thread_ThreadHelper_getThreadIdOffset; +hythread_thread_lock; +hythread_thread_unlock; +hythread_get_state; +hythread_set_state; +hythread_get_thread_id_offset; +hythread_set_thread_stop_callback; +hythread_wait_for_nondaemon_threads; +hythread_increase_nondaemon_threads_count; +hythread_decrease_nondaemon_threads_count; local: *; }; diff --git a/vm/thread/src/thread_init.c b/vm/thread/src/thread_init.c index 19e501b..5732457 100644 --- a/vm/thread/src/thread_init.c +++ b/vm/thread/src/thread_init.c @@ -231,7 +231,7 @@ IDATA VMCALL hythread_global_lock() { // suspend_disable_count must be 0 on potentially // blocking operation to prevent suspension deadlocks, // meaning that the thread is safe for suspension - saved_count = reset_suspend_disable(); + saved_count = hythread_reset_suspend_disable(); r = hymutex_lock(&TM_LIBRARY->TM_LOCK); if (r) return r; @@ -247,7 +247,7 @@ IDATA VMCALL hythread_global_lock() { if (r) return r; } - // do not use set_suspend_disable() as we do not + // do not use hythread_set_suspend_disable() as we do not // want safe points happening under global lock self->disable_count = saved_count; return 0; @@ -424,73 +424,3 @@ UDATA* VMCALL hythread_global (char* name) { return data+index; } - -/* - * Resizable array implementation - */ - -IDATA array_create(array_t *array) { - array_t ptr; - ptr = (array_t)malloc(sizeof(ResizableArrayType)); - if (!ptr) return -1; - ptr->capacity = 1024; - ptr->size =0; - ptr->next_index = 0; - ptr->entries = (array_entry_t)malloc(sizeof(ResizableArrayEntry)*ptr->capacity); - if (!ptr->entries) return -1; - - *array = ptr; - return 0; -} - -IDATA array_destroy(array_t array) { - if (!array) return -1; - free(array->entries); - free(array); - - return 0; -} - -UDATA array_add(array_t array, void *value) { - UDATA index; - if (!array) return 0; - if (array->next_index) { - index = array->next_index; - } else { - index = array->size + 1; - if (index >= array->capacity) { - array->entries = realloc(array->entries, sizeof(void*)*array->capacity*2); - if (!array->entries) return 0; - array->capacity*=2; - } - - array->entries[index].next_free=0; - } - - array->next_index = array->entries[index].next_free; - array->entries[index].entry = value; - array->size++; - - return index; -} - -void *array_delete(array_t array, UDATA index) { - void *return_value; - if (!array || index > array->size || index==0) return NULL; - return_value = array->entries[index].entry; - - array->entries[index].entry = NULL; - array->entries[index].next_free = array->next_index; - array->next_index = index; - - return return_value; -} - -void *array_get(array_t array, UDATA index) { - if (!array || index > array->size || index==0) return NULL; - return array->entries[index].entry; -} - - - - diff --git a/vm/thread/src/thread_native_basic.c b/vm/thread/src/thread_native_basic.c index e80e8ac..5c052a9 100644 --- a/vm/thread/src/thread_native_basic.c +++ b/vm/thread/src/thread_native_basic.c @@ -33,6 +33,7 @@ # define hy_inline #endif //PLATFORM_POSIX +#include #include #include "thread_private.h" @@ -115,7 +116,7 @@ IDATA VMCALL hythread_create_with_group(hythread_t *ret_thread, hythread_group_t new_thread->library = hythread_self()->library; new_thread->priority = priority ? priority : HYTHREAD_PRIORITY_NORMAL; - new_thread->stacksize = stacksize ? stacksize : HY_DEFAULT_STACKSIZE; + new_thread->stacksize = stacksize ? stacksize : TM_DEFAULT_STACKSIZE; //new_thread->suspend_request = suspend ? 1 : 0; start_proc_data = @@ -775,3 +776,139 @@ UDATA hythread_get_thread_times(hythread_t thread, int64* pkernel, int64* puser) UDATA hythread_get_thread_stacksize(hythread_t thread) { return thread->stacksize; } + +IDATA VMCALL hythread_thread_lock(hythread_t thread) { + assert(thread); + return hymutex_lock(&thread->mutex); +} // hythread_thread_lock + +IDATA VMCALL hythread_thread_unlock(hythread_t thread) { + assert(thread); + return hymutex_unlock(&thread->mutex); +} // hythread_thread_unlock + +IDATA VMCALL hythread_get_state(hythread_t thread) { + IDATA state; + assert(thread); + hymutex_lock(&thread->mutex); + state = thread->state; + hymutex_unlock(&thread->mutex); + return state; +} // hythread_get_state + +IDATA VMCALL hythread_set_state(hythread_t thread, IDATA state) { + assert(thread); + hymutex_lock(&thread->mutex); + thread->state = state; + hymutex_unlock(&thread->mutex); + return TM_ERROR_NONE; +} // hythread_set_state + +IDATA VMCALL hythread_get_thread_id_offset() { + return (uint32)&((HyThread *)0)->thread_id; +} // hythread_get_thread_id_offset + +IDATA VMCALL hythread_set_thread_stop_callback(hythread_t thread, + tm_thread_event_callback_proc stop_callback) +{ + IDATA status = hythread_set_safepoint_callback(thread, stop_callback); + + while (thread->suspend_count > 0) { + apr_atomic_dec32((volatile apr_uint32_t *) + &thread->suspend_count); + apr_atomic_dec32((volatile apr_uint32_t *) + &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 + // if safepoint callback isn't set it could be equal to 0. + // + // The following assertion may be false because at each time + // one of the conditions is true, and the other is false, but + // when checking the whole condition it may be failse in the result. + // assert(thread->request > 0 || thread->safepoint_callback == NULL); + + // notify the thread that it may wake up now, + // so that it would eventually reach exception safepoint + // and execute callback + hysem_post(thread->resume_event); + return status; +} // hythread_set_thread_stop_callback + +IDATA VMCALL hythread_wait_for_nondaemon_threads(hythread_t thread, IDATA threads_to_keep) +{ + IDATA status; + hythread_library_t lib; + + assert(thread); + lib = thread->library; + + status = hymutex_lock(&lib->TM_LOCK); + if (status != TM_ERROR_NONE) { + return status; + } + + while (lib->nondaemon_thread_count - threads_to_keep > 0) + { + // check interruption and other problems + status = hycond_wait(&lib->nondaemon_thread_cond, &lib->TM_LOCK); + + TRACE(("TM wait for nondaemons notified, count: %d", + lib->nondaemon_thread_count)); + + if (status != TM_ERROR_NONE) { + hymutex_unlock(&lib->TM_LOCK); + return status; + } + } + + status = hymutex_unlock(&lib->TM_LOCK); + return status; +} // hythread_wait_for_nondaemon_threads + +IDATA VMCALL hythread_increase_nondaemon_threads_count(hythread_t thread) +{ + hythread_library_t lib = thread->library; + IDATA status = hymutex_lock(&lib->TM_LOCK); + if (status != TM_ERROR_NONE) { + return status; + } + lib->nondaemon_thread_count++; + status = hymutex_unlock(&lib->TM_LOCK); + return status; +} // hythread_increase_nondaemon_threads_count_in_library + +IDATA VMCALL hythread_decrease_nondaemon_threads_count(hythread_t thread, IDATA threads_to_keep) +{ + hythread_library_t lib = thread->library; + IDATA status = hymutex_lock(&lib->TM_LOCK); + if (status != TM_ERROR_NONE) { + return status; + } + + if (lib->nondaemon_thread_count <= 0) { + status = hymutex_unlock(&lib->TM_LOCK); + if (status != TM_ERROR_NONE) { + return status; + } + return TM_ERROR_ILLEGAL_STATE; + } + + TRACE(("TM: nondaemons decreased, thread: %p count: %d\n", thread, + lib->nondaemon_thread_count)); + + lib->nondaemon_thread_count--; + if (lib->nondaemon_thread_count - threads_to_keep <= 0) { + status = hycond_notify_all(&lib->nondaemon_thread_cond); + TRACE(("TM: nondaemons all dead, thread: %p count: %d\n", thread, + lib->nondaemon_thread_count)); + if (status != TM_ERROR_NONE) { + hymutex_unlock(&lib->TM_LOCK); + return status; + } + } + + status = hymutex_unlock(&lib->TM_LOCK); + return status; +} // hythread_countdown_nondaemon_threads diff --git a/vm/thread/src/thread_native_condvar.c b/vm/thread/src/thread_native_condvar.c index 57fbe1a..2e99c50 100644 --- a/vm/thread/src/thread_native_condvar.c +++ b/vm/thread/src/thread_native_condvar.c @@ -50,11 +50,11 @@ IDATA condvar_wait_impl(hycond_t *cond, hymutex_t *mutex, I_64 ms, IDATA nano, I return TM_ERROR_INTERRUPT; } - disable_count = reset_suspend_disable(); + disable_count = hythread_reset_suspend_disable(); r = os_cond_timedwait(cond, mutex, ms, nano); - set_suspend_disable(disable_count); + hythread_set_suspend_disable(disable_count); self->current_condition = NULL; // check interrupted flag diff --git a/vm/thread/src/thread_native_fat_monitor.c b/vm/thread/src/thread_native_fat_monitor.c index 1ebeb5d..f4a282c 100644 --- a/vm/thread/src/thread_native_fat_monitor.c +++ b/vm/thread/src/thread_native_fat_monitor.c @@ -223,9 +223,9 @@ IDATA monitor_wait_impl(hythread_monitor_t mon_ptr, I_64 ms, IDATA nano, IDATA i hymutex_unlock(&mon_ptr->mutex); hythread_safe_point(); hythread_exception_safe_point(); - save_count = reset_suspend_disable(); + save_count = hythread_reset_suspend_disable(); hymutex_lock(&mon_ptr->mutex); - set_suspend_disable(save_count); + hythread_set_suspend_disable(save_count); } mon_ptr->recursion_count = saved_recursion; diff --git a/vm/thread/src/thread_native_suspend.c b/vm/thread/src/thread_native_suspend.c index 6168826..5292e64 100644 --- a/vm/thread/src/thread_native_suspend.c +++ b/vm/thread/src/thread_native_suspend.c @@ -429,9 +429,9 @@ IDATA VMCALL hythread_resume_all(hythread_group_t group) /** * Reset disable_count for currect thread. * The method begins suspension safe region. - * Field disable_count is restored in set_suspend_disable() function. + * Field disable_count is restored in hythread_set_suspend_disable() function. */ -int reset_suspend_disable() +int VMCALL hythread_reset_suspend_disable() { hythread_t self = tm_self_tls; int disable_count = self->disable_count; @@ -442,12 +442,12 @@ int reset_suspend_disable() /** * Restores disable_count for current thread, - * which was reset in reset_suspend_disable() function + * which was reset in hythread_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) +void VMCALL hythread_set_suspend_disable(int count) { hythread_t self = tm_self_tls; diff --git a/vm/thread/src/thread_native_thin_monitor.c b/vm/thread/src/thread_native_thin_monitor.c index 4d94440..0040837 100644 --- a/vm/thread/src/thread_native_thin_monitor.c +++ b/vm/thread/src/thread_native_thin_monitor.c @@ -34,6 +34,11 @@ */ //@{ +#if !defined (_IPF_) +// spin with try_lock SPIN_COUNT times +#define SPIN_COUNT 5 +#endif // !defined (_IPF_) + /* * 32bit lock word * |0|------15bit-------|--5bit--|1bit|--10bit------| @@ -65,7 +70,7 @@ HyFatLockTable *lock_table = NULL; -IDATA owns_thin_lock(hythread_t thread, I_32 lockword) { +IDATA VMCALL hythread_owns_thin_lock(hythread_t thread, hythread_thin_monitor_t lockword) { IDATA this_id = thread->thread_id; assert(!IS_FAT_LOCK(lockword)); #ifdef LOCK_RESERVATION @@ -100,15 +105,14 @@ IDATA get_fat_lock_id(hythread_thin_monitor_t *lockword_ptr) { return lockword; } -IDATA is_fat_lock(hythread_thin_monitor_t lockword) { - return IS_FAT_LOCK(lockword); +int VMCALL hythread_is_fat_lock(hythread_thin_monitor_t lockword) { + return (int)IS_FAT_LOCK(lockword); } //forward declaration hythread_monitor_t locktable_get_fat_monitor(IDATA lock_id); IDATA locktable_put_fat_monitor(hythread_monitor_t fat_monitor); hythread_monitor_t locktable_delete_entry(int lock_id); -hythread_monitor_t inflate_lock(hythread_thin_monitor_t *lockword_ptr); //DEBUG INFO BLOCK //char *vm_get_object_class_name(void* ptr); @@ -131,8 +135,8 @@ extern hymutex_t TM_LOCK; void unreserve_self_lock(hythread_thin_monitor_t *lockword_ptr) { U_32 lockword = *lockword_ptr; U_32 lockword_new; - TRACE(("unreserve self_id %d lock owner %d", hythread_get_id(hythread_self()), THREAD_ID(lockword))); - assert(hythread_get_id(hythread_self()) == THREAD_ID(lockword)); + TRACE(("unreserve self_id %d lock owner %d", hythread_get_self_id(), THREAD_ID(lockword))); + assert(hythread_get_self_id() == THREAD_ID(lockword)); assert (!IS_FAT_LOCK(*lockword_ptr)); assert (IS_RESERVED(lockword)); TRACE(("Unreserved self %d \n", ++unreserve_count_self/*, vm_get_object_class_name(lockword_ptr-1)*/)); @@ -150,10 +154,11 @@ void unreserve_self_lock(hythread_thin_monitor_t *lockword_ptr) { } -/* +/** * Used lockword + * Thin monitor functions used java monitor. */ -IDATA unreserve_lock(hythread_thin_monitor_t *lockword_ptr) { +IDATA VMCALL hythread_unreserve_lock(hythread_thin_monitor_t *lockword_ptr) { U_32 lockword = *lockword_ptr; U_32 lockword_new; uint16 lock_id; @@ -251,7 +256,7 @@ IDATA unreserve_lock(hythread_thin_monitor_t *lockword_ptr) { return TM_ERROR_NONE; } #else -IDATA unreserve_lock(I_32* lockword_ptr) { +IDATA VMCALL hythread_unreserve_lock(hythread_thin_monitor_t* lockword_ptr) { return TM_ERROR_NONE; } #endif @@ -304,7 +309,7 @@ IDATA hythread_thin_monitor_try_enter(hythread_thin_monitor_t *lockword_ptr) { if (lock_id == this_id) { if (RECURSION(lockword) == MAX_RECURSION) { //inflate lock in case of recursion overflow - fat_monitor =inflate_lock(lockword_ptr); + fat_monitor = hythread_inflate_lock(lockword_ptr); return hythread_monitor_try_enter(fat_monitor); //break FAT_LOCK; } else { @@ -366,7 +371,7 @@ IDATA hythread_thin_monitor_try_enter(hythread_thin_monitor_t *lockword_ptr) { #ifdef LOCK_RESERVATION // unreserved busy lock else if (IS_RESERVED(lockword)) { - status = unreserve_lock(lockword_ptr); + status = hythread_unreserve_lock(lockword_ptr); if (status != TM_ERROR_NONE) { #ifdef SPIN_COUNT if (status == TM_ERROR_EBUSY) { @@ -407,9 +412,9 @@ IDATA hythread_thin_monitor_enter(hythread_thin_monitor_t *lockword_ptr) { if (IS_FAT_LOCK(*lockword_ptr)) { fat_monitor = locktable_get_fat_monitor(FAT_LOCK_ID(*lockword_ptr)); // find fat_monitor in lock table TRACE((" lock %d\n", FAT_LOCK_ID(*lockword_ptr))); - saved_disable_count=reset_suspend_disable(); + saved_disable_count = hythread_reset_suspend_disable(); status = hythread_monitor_enter(fat_monitor); - set_suspend_disable(saved_disable_count); + hythread_set_suspend_disable(saved_disable_count); return status; // lock fat_monitor } //hythread_safe_point(); @@ -420,7 +425,7 @@ IDATA hythread_thin_monitor_enter(hythread_thin_monitor_t *lockword_ptr) { return TM_ERROR_NONE; } TRACE(("inflate_contended thin_lcok%d\n", ++inflate_contended)); - inflate_lock(lockword_ptr); + hythread_inflate_lock(lockword_ptr); return TM_ERROR_NONE; } @@ -470,13 +475,13 @@ IDATA thin_monitor_wait_impl(hythread_thin_monitor_t *lockword_ptr, I_64 ms, IDA if (!IS_FAT_LOCK(lockword)) { // check if the current thread owns lock - if (!owns_thin_lock(this_thread, lockword)) { + if (!hythread_owns_thin_lock(this_thread, lockword)) { TRACE(("ILLEGAL_STATE %wait d\n", FAT_LOCK_ID(lockword))); return TM_ERROR_ILLEGAL_STATE; } TRACE(("inflate_wait%d\n", ++inflate_waited)); // if it is not a thin lock, inflate it - fat_monitor = inflate_lock(lockword_ptr); + fat_monitor = hythread_inflate_lock(lockword_ptr); } else { // otherwise, get the appropriate fat lock fat_monitor = locktable_get_fat_monitor(FAT_LOCK_ID(lockword)); @@ -552,7 +557,7 @@ IDATA hythread_thin_monitor_notify(hythread_thin_monitor_t *lockword_ptr) { return hythread_monitor_notify(fat_monitor); } // check if the current thread owns lock - if (!owns_thin_lock(tm_self_tls, lockword)) { + if (!hythread_owns_thin_lock(tm_self_tls, lockword)) { return TM_ERROR_ILLEGAL_STATE; } @@ -573,7 +578,7 @@ IDATA hythread_thin_monitor_notify_all(hythread_thin_monitor_t *lockword_ptr) { return hythread_monitor_notify_all(fat_monitor); } // check if the current thread owns lock - if (!owns_thin_lock(tm_self_tls, lockword)) { + if (!hythread_owns_thin_lock(tm_self_tls, lockword)) { return TM_ERROR_ILLEGAL_STATE; } return TM_ERROR_NONE; @@ -599,7 +604,7 @@ IDATA hythread_thin_monitor_destroy(hythread_thin_monitor_t *lockword_ptr) { /* * Inflates the compressed lockword into fat fat_monitor */ -hythread_monitor_t VMCALL inflate_lock(hythread_thin_monitor_t *lockword_ptr) { +hythread_monitor_t VMCALL hythread_inflate_lock(hythread_thin_monitor_t *lockword_ptr) { hythread_monitor_t fat_monitor; IDATA status; IDATA fat_monitor_id; @@ -626,7 +631,7 @@ hythread_monitor_t VMCALL inflate_lock(hythread_thin_monitor_t *lockword_ptr) { assert(!IS_RESERVED(lockword)); #endif - assert(owns_thin_lock(tm_self_tls, lockword)); + assert(hythread_owns_thin_lock(tm_self_tls, lockword)); assert(!hythread_is_suspend_enabled()); TRACE (("inflation begin for %x thread: %d", lockword, tm_self_tls->thread_id)); @@ -644,7 +649,7 @@ hythread_monitor_t VMCALL inflate_lock(hythread_thin_monitor_t *lockword_ptr) { } fat_monitor_id = locktable_put_fat_monitor(fat_monitor); // put fat_monitor into lock table set_fat_lock_id(lockword_ptr, fat_monitor_id); - TRACE(("inflate_lock %d thread: %d\n", FAT_LOCK_ID(*lockword_ptr), tm_self_tls->thread_id)); + TRACE(("hythread_inflate_lock %d thread: %d\n", FAT_LOCK_ID(*lockword_ptr), tm_self_tls->thread_id)); //assert(FAT_LOCK_ID(*lockword_ptr) != 2); TRACE(("FAT ID : 0x%x", *lockword_ptr)); fat_monitor->inflate_count++; diff --git a/vm/thread/src/thread_native_tls.c b/vm/thread/src/thread_native_tls.c index 0d4a1d3..9d94514 100644 --- a/vm/thread/src/thread_native_tls.c +++ b/vm/thread/src/thread_native_tls.c @@ -191,15 +191,4 @@ UDATA VMCALL hythread_tls_get_offset(hythread_tls_key_t key) { return ((UDATA)&((hythread_t)0)->thread_local_storage) + (key * sizeof(void*)); } - -/* - * Class: org_apache_harmony_drlvm_thread_ThreadHelper - * Method: getThreadIdOffset - * Signature: ()I - */ -jint JNICALL Java_org_apache_harmony_drlvm_thread_ThreadHelper_getThreadIdOffset(JNIEnv *e, jclass c) { - return (uint32)&((HyThread *)0)->thread_id; -} - - //@} diff --git a/vm/thread/src/thread_private.h b/vm/thread/src/thread_private.h index 30772e7..0817228 100644 --- a/vm/thread/src/thread_private.h +++ b/vm/thread/src/thread_private.h @@ -50,27 +50,10 @@ #define RET_ON_ERROR(stat) if (stat) { return -1; } #define CONVERT_ERROR(stat) (stat) -#define MAX_OWNED_MONITOR_NUMBER 200 //FIXME: switch to dynamic resize #define FAST_LOCAL_STORAGE_SIZE 10 #define INITIAL_FAT_TABLE_ENTRIES 16*1024 //make this table exapandible if workloads show it is necessary -#define HY_DEFAULT_STACKSIZE 512 * 1024 // if default stack size is not through -Xss parameter, it is 256kb - - -#if !defined (_IPF_) -//use lock reservation -#define LOCK_RESERVATION -// spin with try_lock SPIN_COUNT times -#define SPIN_COUNT 5 - -#endif // !defined (_IPF_) - -#if defined(_WIN32) && !defined (_EM64T_) -//use optimized asm monitor enter and exit helpers -#define ASM_MONITOR_HELPER -#endif - #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ @@ -147,7 +130,7 @@ typedef struct HyThread { * for current thread only. * * Also disable_count could be reset to value 0 and restored in - * reset_suspend_disable()/set_suspend_disable() function + * hythread_set_suspend_disable()/hythread_set_suspend_disable() function * for current thread only. * * Function hythread_exception_safe_point() sets disable_count to @@ -509,8 +492,6 @@ extern apr_threadkey_t *TM_THREAD_KEY; // Key used to store tm_thread_t structur extern int max_group_index; // max number of groups -extern int total_started_thread_count; // Total started thread counter. - extern HyFatLockTable *lock_table; #define THREAD_ID_SIZE 16 //size of thread ID in bits. Also defines max number of threads @@ -520,23 +501,6 @@ extern HyFatLockTable *lock_table; /** * Internal TM functions */ - -/** -* tm_reset_suspend_disable() reset suspend_disable to 0, and return old value. -* It should be used with tm_set_suspend_disable() to implement safe points -* Will be used in tm_safe_point(), tm_mutex_lock(), tm_cond_wait(). -*/ - -int reset_suspend_disable(); -void set_suspend_disable(int count); - -/* thin monitor functions used java monitor - */ -IDATA is_fat_lock(hythread_thin_monitor_t lockword); -IDATA owns_thin_lock(hythread_t thread, I_32 lockword); -hythread_monitor_t inflate_lock(hythread_thin_monitor_t *lockword_ptr); -IDATA unreserve_lock(hythread_thin_monitor_t *lockword_ptr); - IDATA VMCALL hythread_get_group(hythread_group_t *group, hythread_t thread); /** * Auxiliary function to throw java.lang.InterruptedException @@ -564,34 +528,6 @@ IDATA monitor_wait_impl(hythread_monitor_t mon_ptr, I_64 ms, IDATA nano, IDATA i IDATA thin_monitor_wait_impl(hythread_thin_monitor_t *lockword_ptr, I_64 ms, IDATA nano, IDATA interruptable); IDATA sem_wait_impl(hysem_t sem, I_64 ms, IDATA nano, IDATA interruptable); -typedef struct ResizableArrayEntry { - void *entry; - UDATA next_free; -} ResizableArrayEntry; - -typedef struct ResizableArrayEntry *array_entry_t; - -typedef struct ResizableArrayType { - UDATA size; - UDATA capacity; - UDATA next_index; - array_entry_t entries; -} ResizableArrayType; -typedef struct ResizableArrayType *array_t; - - -IDATA array_create(array_t *array); -IDATA array_destroy(array_t array); -UDATA array_add(array_t array, void *value); -void *array_delete(array_t array, UDATA index); -void *array_get(array_t array, UDATA index); - -/** - * Auxiliary function to update thread count - */ -void thread_start_count(); -void thread_end_count(); - /* * portability functions, private for thread module */ diff --git a/vm/vmcore/include/Class.h b/vm/vmcore/include/Class.h index 298fc72..685c7c2 100644 --- a/vm/vmcore/include/Class.h +++ b/vm/vmcore/include/Class.h @@ -50,7 +50,7 @@ struct ClassLoader; class JIT; struct Global_Env; class Package; -class VM_thread; +struct VM_thread; struct AnnotationTable; diff --git a/vm/vmcore/include/exceptions_type.h b/vm/vmcore/include/exceptions_type.h index 3cd73f9..bf76038 100644 --- a/vm/vmcore/include/exceptions_type.h +++ b/vm/vmcore/include/exceptions_type.h @@ -30,11 +30,12 @@ #ifdef __cplusplus extern "C" { #endif + struct Exception { - ManagedObject* exc_object; - Class* exc_class; + struct ManagedObject* exc_object; + struct Class* exc_class; const char* exc_message; - ManagedObject* exc_cause; + struct ManagedObject* exc_cause; }; #ifdef __cplusplus diff --git a/vm/vmcore/include/thread_manager.h b/vm/vmcore/include/thread_manager.h index d1ac4d6..8f3c5d8 100644 --- a/vm/vmcore/include/thread_manager.h +++ b/vm/vmcore/include/thread_manager.h @@ -14,29 +14,251 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** - * @author Andrey Chernyshev - * @version $Revision: 1.1.2.1.4.4 $ - */ - #ifndef THREAD_MANAGER_HEADER #define THREAD_MANAGER_HEADER -#include "vm_threads.h" +#include "open/jthread.h" +#include "open/thread_externals.h" +#include "exceptions_type.h" +#define GC_BYTES_IN_THREAD_LOCAL (20 * sizeof(void *)) +#define CONVERT_ERROR(stat) (stat) #ifdef __cplusplus -extern "C" { +extern "C" +{ +#endif + +struct jvmti_frame_pop_listener; +struct JVMTISingleStepState; +struct ClassLoader; +struct Exception; + +// These are thread level gc states. +enum gc_state +{ + zero = 0, + gc_moving_to_safepoint, + gc_at_safepoint, + gc_enumeration_done +}; + +struct VM_thread +{ + /** + * Memory pool where this structure is allocated. + * This pool should be used by current thread for memory allocations. + */ + apr_pool_t *pool; + + /** + * JNI environment associated with this thread. + */ + JNIEnv *jni_env; + + /** + * Class loader which loads native library and calls to its JNI_OnLoad + */ + struct ClassLoader *onload_caller; + + /** + * Flag to detect if a class is not found on bootclasspath, + * as opposed to linkage errors. + * Used for implementing default delegation model. + */ + unsigned char class_not_found; + + // In case exception is thrown, Exception object is put here + // TODO: Needs to be replaced with jobject! + //volatile ManagedObject* p_exception_object; + volatile struct Exception thread_exception; + + // For support of JVMTI events: EXCEPTION, EXCEPTION_CATCH + // If p_exception_object is set and p_exception_object_ti is not + // - EXCEPTION event should be generated + // If p_exception_object_ti is set and p_exception_object is not + // - EXCEPTION_CATCH even should be generated + volatile struct ManagedObject *p_exception_object_ti; + + // flag which indicate that guard page on the stak should be restored + unsigned char restore_guard_page; + + // thread stack address + void *stack_addr; + + // thread stack size + unsigned int stack_size; + + // Should JVMTI code be notified about exception in p_exception_object + unsigned char ti_exception_callback_pending; + + // ?? + enum gc_state gc_status; + int finalize_thread_flags; + // Flag indicating whether thread stopped. Duplicate of thread_state? + unsigned char is_stoped; + + JVMTILocalStorage jvmti_local_storage; + // Buffer used to create instructions instead of original instruction + // to transfer execution control back to the code after breakpoint + // has been processed + jbyte jvmti_jit_breakpoints_handling_buffer[50]; + struct jvmti_frame_pop_listener *frame_pop_listener; + struct JVMTISingleStepState *ss_state; + void *jvmti_saved_exception_registers; + + // CPU registers. + void *regs; + + // This field is private the to M2nFrame module, init code should set it to NULL + // Informational frame - created when native is called from Java, + // used to store local handles (jobjects) + registers. + // =0 if there is no m2n frame. + void *last_m2n_frame; + + // GC Information + unsigned char _gc_private_information[GC_BYTES_IN_THREAD_LOCAL]; + void *native_handles; + void *gc_frames; + //gc_enable_disable_state gc_enabled_status; + unsigned char gc_wait_for_enumeration; + unsigned char restore_context_after_gc_and_resume; + +#if defined(PLATFORM_POSIX) && defined(_IPF_) + // Linux/IPF + hysem_t suspend_sem; // To suspend thread in signal handler + hysem_t suspend_self; // To suspend current thread for signal handler + uint64 suspended_state; // Flag to indicate how the one thread is suspended + // Possible values: + // NOT_SUSPENDED, + // SUSPENDED_IN_SIGNAL_HANDLER, + // SUSPENDED_IN_DISABLE_GC_FOR_THREAD + uint64 t[2]; // t[0] <= rnat, t[1] <= bspstore for current thread context + // t[0] <= rnat, t[1] <= bsp for other thread context #endif -void free_this_thread_block(VM_thread *); -VM_thread * get_a_thread_block(JavaVM_Internal * java_vm); -VM_thread * allocate_thread_block(JavaVM_Internal * java_vm); + void *lastFrame; + void *firstFrame; + int interpreter_state; + void **stack_end; /// The upper boundary of the stack to scan when verifying stack enumeration +}; + +/** + * Java-specific context that is attached to tm_thread control structure by Java layer + */ +struct JVMTIThread +{ + + /** + * JNI env associated with this Java thread + */ + JNIEnv *jenv; + + /** + * jthread object which is associated with tm_thread + */ + jthread thread_object; + + /** + * Conditional variable which is used to wait/notify on java monitors. + */ + hycond_t monitor_condition; + + /** + * Exception that has to be thrown in stopped thread + */ + jthrowable stop_exception; + + /** + * Blocked on monitor times count + */ + jlong blocked_count; + + /** + * Blocked on monitor time in nanoseconds + */ + jlong blocked_time; + + /** + * Waited on monitor times count + */ + jlong waited_count; + + /** + * Waited on monitor time in nanoseconds + */ + jlong waited_time; + + /** + * JVM TI local storage + */ + JVMTILocalStorage jvmti_local_storage; + + /** + * Monitor this thread is blocked on. + */ + jobject contended_monitor; + + /** + * Monitor this thread waits on. + */ + jobject wait_monitor; + + /** + * Monitors for which this thread is owner. + */ + jobject *owned_monitors; + + /** + * owned monitors count. + */ + int owned_monitors_nmb; + + /** + * APR pool for this structure + */ + apr_pool_t *pool; + + /** + * weak reference to corresponding java.lang.Thread instance + */ + jobject thread_ref; + + /** + * Is this thread daemon? + */ + IDATA daemon; +}; + +/** + * Java thread creation attributes. + */ +struct jthread_thread_attr +{ + + /** + * Thread scheduling priority. + */ + jint priority; + + /** + * Thread stack size. + */ + jint stacksize; + + /** + * Denotes whether Java thread is daemon. + * JVM exits when the only threads running are daemon threads. + */ + jboolean daemon; -extern volatile VM_thread *p_the_safepoint_control_thread; // only set when a gc is happening -extern volatile safepoint_state global_safepoint_status; + /** + * JVM TI Environment. + */ + jvmtiEnv *jvmti_env; +}; #ifdef __cplusplus } diff --git a/vm/vmcore/include/vm_core_types.h b/vm/vmcore/include/vm_core_types.h index f877afa..44eb478 100644 --- a/vm/vmcore/include/vm_core_types.h +++ b/vm/vmcore/include/vm_core_types.h @@ -44,7 +44,7 @@ struct LilCodeStub; struct M2nFrame; struct ManagedObject; class NativeObjectHandles; -class VM_thread; +struct VM_thread; class Package; class Package_Table; class Properties; diff --git a/vm/vmcore/include/vm_threads.h b/vm/vmcore/include/vm_threads.h index 32cf545..672cdc0 100644 --- a/vm/vmcore/include/vm_threads.h +++ b/vm/vmcore/include/vm_threads.h @@ -14,16 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/** - * @author Andrey Chernyshev - * @version $Revision: 1.1.2.2.4.4 $ - */ - #ifndef _VM_THREADS_H_ #define _VM_THREADS_H_ - #ifdef PLATFORM_POSIX #include #include "platform_lowlevel.h" @@ -34,175 +28,93 @@ #include #include "open/types.h" -//#include "open/hythread.h" -#include +#include "open/hythread.h" +#include "open/hythread_ext.h" #include "open/ti_thread.h" - -#include "vm_core_types.h" -#include "object_layout.h" +#include "open/jthread.h" #include "open/vm_gc.h" -#include "exceptions_type.h" + #include "jvmti.h" #include "jni_direct.h" +#include "thread_manager.h" +#include "vm_core_types.h" +#include "object_layout.h" - -// #define tmn_suspend_disable assert(hythread_is_suspend_enabled());hythread_suspend_disable #define tmn_suspend_enable assert(!hythread_is_suspend_enabled());hythread_suspend_enable #define tmn_suspend_disable_recursive hythread_suspend_disable #define tmn_suspend_enable_recursive hythread_suspend_enable -#define GC_BYTES_IN_THREAD_LOCAL (20 * sizeof(void *)) - -// These are thread level gc states. -enum gc_state { - zero = 0, - gc_moving_to_safepoint, - gc_at_safepoint, - gc_enumeration_done -}; - - -struct jvmti_frame_pop_listener; -struct JVMTISingleStepState; - -class VmRegisterContext; - -class VM_thread { - -public: - /** - * Memory pool where this structure is allocated. - * This pool should be used by current thread for memory allocations. - */ - apr_pool_t * pool; - - /** - * JNI environment associated with this thread. - */ - JNIEnv_Internal * jni_env; - - /** - * Class loader which loads native library and calls to its JNI_OnLoad - */ - ClassLoader* onload_caller; - - /** - * Flag to detect if a class is not found on bootclasspath, - * as opposed to linkage errors. - * Used for implementing default delegation model. - */ - bool class_not_found; - - // In case exception is thrown, Exception object is put here - // TODO: Needs to be replaced with jobject! - //volatile ManagedObject* p_exception_object; - volatile Exception thread_exception; - - // For support of JVMTI events: EXCEPTION, EXCEPTION_CATCH - // If p_exception_object is set and p_exception_object_ti is not - // - EXCEPTION event should be generated - // If p_exception_object_ti is set and p_exception_object is not - // - EXCEPTION_CATCH even should be generated - volatile ManagedObject* p_exception_object_ti; - - // flag which indicate that guard page on the stak should be restored - bool restore_guard_page; - - // thread stack address - void* stack_addr; - - // thread stack size - unsigned int stack_size; - - // Should JVMTI code be notified about exception in p_exception_object - bool ti_exception_callback_pending; - - // ?? - gc_state gc_status; - int finalize_thread_flags; - // Flag indicating whether thread stopped. Duplicate of thread_state? - bool is_stoped; - - JVMTILocalStorage jvmti_local_storage; - // Buffer used to create instructions instead of original instruction - // to transfer execution control back to the code after breakpoint - // has been processed - jbyte jvmti_jit_breakpoints_handling_buffer[50]; - jvmti_frame_pop_listener *frame_pop_listener; - JVMTISingleStepState *ss_state; - Registers jvmti_saved_exception_registers; - - // CPU registers. - Registers regs; - - // This field is private the to M2nFrame module, init code should set it to NULL - // Informational frame - created when native is called from Java, - // used to store local handles (jobjects) + registers. - // =0 if there is no m2n frame. - M2nFrame* last_m2n_frame; - - // GC Information - Byte _gc_private_information[GC_BYTES_IN_THREAD_LOCAL]; - NativeObjectHandles* native_handles; - GcFrame* gc_frames; - //gc_enable_disable_state gc_enabled_status; - bool gc_wait_for_enumeration; - bool restore_context_after_gc_and_resume; - -#if defined(PLATFORM_POSIX) && defined(_IPF_) - // Linux/IPF - sem_t suspend_sem; // To suspend thread in signal handler - sem_t suspend_self; // To suspend current thread for signal handler - uint64 suspended_state; // Flag to indicate how the one thread is suspended - // Possible values: - // NOT_SUSPENDED, - // SUSPENDED_IN_SIGNAL_HANDLER, - // SUSPENDED_IN_DISABLE_GC_FOR_THREAD - uint64 t[2]; // t[0] <= rnat, t[1] <= bspstore for current thread context - // t[0] <= rnat, t[1] <= bsp for other thread context -#endif - - void *lastFrame; - void *firstFrame; - int interpreter_state; - void** stack_end; /// The upper boundary of the stack to scan when verifying stack enumeration - - void* get_ip_from_regs() { return regs.get_ip(); } - void reset_regs_ip() { return regs.reset_ip(); } - +typedef VM_thread *vm_thread_accessor(); +VMEXPORT extern vm_thread_accessor *get_thread_ptr; -}; +inline void vm_set_exception_registers(VM_thread * thread, Registers & regs) +{ + if (!thread->regs) { + thread->regs = malloc(sizeof(Registers)); + assert(thread->regs); + } + *(Registers *) thread->regs = regs; +} -typedef VM_thread *vm_thread_accessor(); -VMEXPORT extern vm_thread_accessor *get_thread_ptr; +inline void *vm_get_ip_from_regs(VM_thread * thread) +{ + return ((Registers *) thread->regs)->get_ip(); +} -//VMEXPORT VM_thread *get_vm_thread(hythread_t thr); -//VMEXPORT VM_thread *get_vm_thread_self(); +inline void vm_reset_ip_from_regs(VM_thread * thread) +{ + ((Registers *) thread->regs)->reset_ip(); +} -inline VM_thread *get_vm_thread_fast_self() { - register hythread_t thr = hythread_self(); +inline void vm_set_jvmti_saved_exception_registers(VM_thread * thread, + Registers & regs) +{ + if (!thread->jvmti_saved_exception_registers) { + thread->jvmti_saved_exception_registers = malloc(sizeof(Registers)); + assert(thread->jvmti_saved_exception_registers); + } + *(Registers *) thread->jvmti_saved_exception_registers = regs; +} - return thr ? ((VM_thread *)hythread_tls_get(thr, TM_THREAD_VM_TLS_KEY)) : NULL; +inline VM_thread *get_vm_thread_fast_self() +{ + register hythread_t thr = hythread_self(); + return thr ? ((VM_thread *) hythread_tls_get(thr, TM_THREAD_VM_TLS_KEY)) : + NULL; } -inline VM_thread *get_vm_thread(hythread_t thr) { +inline VM_thread *get_vm_thread(hythread_t thr) +{ if (thr == NULL) { return NULL; } - return (VM_thread *)hythread_tls_get(thr, TM_THREAD_VM_TLS_KEY); + return (VM_thread *) hythread_tls_get(thr, TM_THREAD_VM_TLS_KEY); } VMEXPORT void init_TLS_data(); -VMEXPORT void set_TLS_data(VM_thread *thread) ; +VMEXPORT void set_TLS_data(VM_thread * thread); uint16 get_self_stack_key(); #define p_TLS_vmthread (get_vm_thread_fast_self()) -Registers *thread_gc_get_context(VM_thread *, VmRegisterContext &); +//Registers *thread_gc_get_context(VM_thread *, VmRegisterContext &); void thread_gc_set_context(VM_thread *); -struct Global_Env; +/** + * Auxiliary function to update thread count + */ +void jthread_start_count(); +void jthread_end_count(); + +//struct Global_Env; + +void free_this_thread_block(VM_thread *); +VM_thread *get_a_thread_block(JavaVM_Internal * java_vm); +VM_thread *allocate_thread_block(JavaVM_Internal * java_vm); + +extern volatile VM_thread *p_the_safepoint_control_thread; // only set when a gc is happening +extern volatile safepoint_state global_safepoint_status; #endif //!_VM_THREADS_H_ diff --git a/vm/vmcore/src/gc/root_set_enum_common.cpp b/vm/vmcore/src/gc/root_set_enum_common.cpp index 207e755..54e1cec 100644 --- a/vm/vmcore/src/gc/root_set_enum_common.cpp +++ b/vm/vmcore/src/gc/root_set_enum_common.cpp @@ -271,9 +271,9 @@ void vm_enumerate_root_set_single_thread_not_on_stack(VM_thread *thread) } if (thread->native_handles) - thread->native_handles->enumerate(); + ((NativeObjectHandles*)(thread->native_handles))->enumerate(); if (thread->gc_frames) { - thread->gc_frames->enumerate(); + ((GcFrame*)(thread->gc_frames))->enumerate(); } } //vm_enumerate_root_set_single_thread_not_on_stack diff --git a/vm/vmcore/src/jvmti/jvmti_break_intf.cpp b/vm/vmcore/src/jvmti/jvmti_break_intf.cpp index 65804fe..86383a1 100644 --- a/vm/vmcore/src/jvmti/jvmti_break_intf.cpp +++ b/vm/vmcore/src/jvmti/jvmti_break_intf.cpp @@ -593,7 +593,7 @@ VMBreakPoints::process_native_breakpoint() // JVMTI handles it, and registers context is saved for us in TLS VM_thread *vm_thread = p_TLS_vmthread; lock(); - Registers regs = vm_thread->jvmti_saved_exception_registers; + Registers regs = *(Registers*)vm_thread->jvmti_saved_exception_registers; NativeCodePtr addr = (NativeCodePtr)regs.get_ip(); TRACE2("jvmti.break", "Native breakpoint occured: " << addr); @@ -703,7 +703,7 @@ VMBreakPoints::process_native_breakpoint() // Registers in TLS can be changed in user callbacks // It should be restored to keep original address of instrumented instruction // Exception/signal handlers use it when HWE occurs in instruction buffer - vm_thread->jvmti_saved_exception_registers = regs; + vm_set_jvmti_saved_exception_registers(vm_thread, regs); unlock(); // Now we need to return back to normal code execution, it is @@ -1367,7 +1367,7 @@ bool jvmti_jit_breakpoint_handler(Registers *regs) // Store possibly corrected location regs->set_ip((void*)native_location); // Copy original registers to TLS - vm_thread->jvmti_saved_exception_registers = *regs; + vm_set_jvmti_saved_exception_registers(vm_thread, *regs); // Set return address for exception handler #if defined (PLATFORM_POSIX) || defined(_EM64T_) regs->set_ip((void*)process_native_breakpoint_event); diff --git a/vm/vmcore/src/jvmti/jvmti_event.cpp b/vm/vmcore/src/jvmti/jvmti_event.cpp index 8a33d9c..097584b 100644 --- a/vm/vmcore/src/jvmti/jvmti_event.cpp +++ b/vm/vmcore/src/jvmti/jvmti_event.cpp @@ -247,7 +247,7 @@ jvmtiSetEventNotificationMode(jvmtiEnv* env, return JVMTI_ERROR_INVALID_THREAD; jint thread_state; - IDATA UNUSED status = jthread_get_state(event_thread, &thread_state); + IDATA UNUSED status = jthread_get_jvmti_state(event_thread, &thread_state); assert(status == TM_ERROR_NONE); if (!(thread_state & JVMTI_THREAD_STATE_ALIVE)) diff --git a/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp b/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp index ed3b9e7..f88055f 100644 --- a/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp +++ b/vm/vmcore/src/jvmti/jvmti_pop_frame.cpp @@ -38,7 +38,8 @@ static void jvmti_pop_frame_callback() { TRACE(("JVMTI PopFrame callback is called")); - frame_type type = m2n_get_frame_type(p_TLS_vmthread->last_m2n_frame); + frame_type type = + m2n_get_frame_type((M2nFrame*)(p_TLS_vmthread->last_m2n_frame)); // frame wasn't requested to be popped if (FRAME_POP_NOW != (FRAME_POP_NOW & type)) { diff --git a/vm/vmcore/src/jvmti/jvmti_roots.cpp b/vm/vmcore/src/jvmti/jvmti_roots.cpp index 0f6793d..a4ac915 100644 --- a/vm/vmcore/src/jvmti/jvmti_roots.cpp +++ b/vm/vmcore/src/jvmti/jvmti_roots.cpp @@ -273,9 +273,9 @@ static void ti_enumerate_thread_not_on_stack(TIEnv* ti_env, VM_thread* thread) } if (thread->native_handles) - thread->native_handles->enumerate(); + ((NativeObjectHandles*)(thread->native_handles))->enumerate(); if (thread->gc_frames) { - thread->gc_frames->enumerate(); + ((GcFrame*)(thread->gc_frames))->enumerate(); } } diff --git a/vm/vmcore/src/jvmti/jvmti_step.cpp b/vm/vmcore/src/jvmti/jvmti_step.cpp index 2e325e5..ae934fe 100644 --- a/vm/vmcore/src/jvmti/jvmti_step.cpp +++ b/vm/vmcore/src/jvmti/jvmti_step.cpp @@ -485,7 +485,7 @@ static void jvmti_start_single_step_in_virtual_method(DebugUtilsTI *ti, VMBreakP { #if (defined _IA32_) || (defined _EM64T_) VM_thread *vm_thread = p_TLS_vmthread; - Registers *regs = &vm_thread->jvmti_saved_exception_registers; + Registers regs = *(Registers*)(vm_thread->jvmti_saved_exception_registers); // This is a virtual breakpoint set exactly on the call // instruction for the virtual method. In this place it is // possible to determine the target method in runtime @@ -500,11 +500,11 @@ static void jvmti_start_single_step_in_virtual_method(DebugUtilsTI *ti, VMBreakP // Invokevirtual uses indirect call from VTable. The base // address is in the register, offset is in displacement * // scale. This method is much faster than - VTable* vtable = (VTable*)disasm->get_reg_value(op.base, regs); + VTable* vtable = (VTable*)disasm->get_reg_value(op.base, ®s); assert(vtable); // For x86 based architectures offset cannot be longer than 32 // bits, so unsigned is ok here - unsigned offset = (unsigned)((POINTER_SIZE_INT)disasm->get_reg_value(op.index, regs) * + unsigned offset = (unsigned)((POINTER_SIZE_INT)disasm->get_reg_value(op.index, ®s) * op.scale + op.disp); method = class_get_method_from_vt_offset(vtable, offset); } @@ -513,7 +513,7 @@ static void jvmti_start_single_step_in_virtual_method(DebugUtilsTI *ti, VMBreakP // This is invokeinterface bytecode which uses register // call so we need to search through all methods for this // one to find it, no way to get vtable and offset in it - NativeCodePtr ip = disasm->get_target_address_from_context(regs); + NativeCodePtr ip = disasm->get_target_address_from_context(®s); Global_Env * vm_env = jni_get_vm_env(vm_thread->jni_env); CodeChunkInfo *cci = vm_env->vm_methods->find(ip); if (cci) diff --git a/vm/vmcore/src/jvmti/jvmti_thread.cpp b/vm/vmcore/src/jvmti/jvmti_thread.cpp index c810109..a5325c1 100644 --- a/vm/vmcore/src/jvmti/jvmti_thread.cpp +++ b/vm/vmcore/src/jvmti/jvmti_thread.cpp @@ -81,7 +81,7 @@ jvmtiGetThreadState(jvmtiEnv* env, if (thread_state_ptr == NULL){ return JVMTI_ERROR_NULL_POINTER; } - IDATA UNUSED status = jthread_get_state(thread, thread_state_ptr); + IDATA UNUSED status = jthread_get_jvmti_state(thread, thread_state_ptr); assert(status == TM_ERROR_NONE); return JVMTI_ERROR_NONE; @@ -469,7 +469,7 @@ jvmtiInterruptThread(jvmtiEnv* env, } jint thread_state; - IDATA UNUSED status = jthread_get_state(thread, &thread_state); + IDATA UNUSED status = jthread_get_jvmti_state(thread, &thread_state); assert(status == TM_ERROR_NONE); if (! (JVMTI_THREAD_STATE_ALIVE & thread_state)) diff --git a/vm/vmcore/src/kernel_classes/native/java_lang_VMThreadManager.cpp b/vm/vmcore/src/kernel_classes/native/java_lang_VMThreadManager.cpp index 240b336..e74ed03 100644 --- a/vm/vmcore/src/kernel_classes/native/java_lang_VMThreadManager.cpp +++ b/vm/vmcore/src/kernel_classes/native/java_lang_VMThreadManager.cpp @@ -29,6 +29,7 @@ #include "open/ti_thread.h" #include "open/thread_externals.h" #include "jni_utils.h" +#include "thread_manager.h" /* * Class: java_lang_VMThreadManager @@ -148,7 +149,7 @@ JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_sleep JNIEXPORT jlong JNICALL Java_java_lang_VMThreadManager_init (JNIEnv *jenv, jclass clazz, jobject thread, jobject ref, jlong oldThread) { - return jthread_thread_init(NULL, jenv, thread, ref, oldThread); + return jthread_thread_init(jenv, thread, ref, (hythread_t)oldThread); } /* @@ -256,7 +257,7 @@ JNIEXPORT jint JNICALL Java_java_lang_VMThreadManager_getState jint state; IDATA stat; - stat = jthread_get_state(jthread, &state); + stat = jthread_get_jvmti_state(jthread, &state); assert(stat == TM_ERROR_NONE); return state; } diff --git a/vm/vmcore/src/kernel_classes/native/org_apache_harmony_lang_management_ThreadMXBeanImpl.cpp b/vm/vmcore/src/kernel_classes/native/org_apache_harmony_lang_management_ThreadMXBeanImpl.cpp index 308f12a..21ddd04 100644 --- a/vm/vmcore/src/kernel_classes/native/org_apache_harmony_lang_management_ThreadMXBeanImpl.cpp +++ b/vm/vmcore/src/kernel_classes/native/org_apache_harmony_lang_management_ThreadMXBeanImpl.cpp @@ -289,7 +289,7 @@ Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isSuspendedImpl(JNIEnv { jint thread_state; TRACE2("management", "ThreadMXBeanImpl_isSuspendedImpl invocation"); - IDATA UNUSED status = jthread_get_state(thread, &thread_state); + IDATA UNUSED status = jthread_get_jvmti_state(thread, &thread_state); assert(!status); return thread_state & TM_THREAD_STATE_SUSPENDED; }; diff --git a/vm/vmcore/src/object/object_handles.cpp b/vm/vmcore/src/object/object_handles.cpp index b66ab86..303cf57 100644 --- a/vm/vmcore/src/object/object_handles.cpp +++ b/vm/vmcore/src/object/object_handles.cpp @@ -81,7 +81,7 @@ GcFrame::GcFrame(unsigned size_hint) nodes = gc_frame_node_new(size_hint); else nodes = NULL; - next = p_TLS_vmthread->gc_frames; + next = (GcFrame*)p_TLS_vmthread->gc_frames; p_TLS_vmthread->gc_frames = this; } @@ -89,7 +89,7 @@ GcFrame::~GcFrame() { assert(!hythread_is_suspend_enabled()); - assert(p_TLS_vmthread->gc_frames==this); + assert(((GcFrame*)p_TLS_vmthread->gc_frames) == this); p_TLS_vmthread->gc_frames = next; next = NULL; GcFrameNode* c; @@ -331,14 +331,14 @@ VMEXPORT // temporary solution for interpreter unplug NativeObjectHandles::NativeObjectHandles() : handles(NULL) { - next = p_TLS_vmthread->native_handles; + next = (NativeObjectHandles*)p_TLS_vmthread->native_handles; p_TLS_vmthread->native_handles = this; } VMEXPORT // temporary solution for interpreter unplug NativeObjectHandles::~NativeObjectHandles() { - assert(p_TLS_vmthread->native_handles==this); + assert(((NativeObjectHandles*)p_TLS_vmthread->native_handles) == this); p_TLS_vmthread->native_handles = next; next = NULL; oh_free_handles(handles); @@ -386,7 +386,7 @@ ObjectHandle oh_allocate_local_handle() m2n_set_local_handles(lm2nf, hs); } else { assert(p_TLS_vmthread->native_handles); - res = p_TLS_vmthread->native_handles->allocate(); + res = ((NativeObjectHandles*)p_TLS_vmthread->native_handles)->allocate(); } return res; } diff --git a/vm/vmcore/src/thread/helpers/thread_helpers.cpp b/vm/vmcore/src/thread/helpers/thread_helpers.cpp index 20d750a..1836e5a 100644 --- a/vm/vmcore/src/thread/helpers/thread_helpers.cpp +++ b/vm/vmcore/src/thread/helpers/thread_helpers.cpp @@ -22,11 +22,10 @@ * This file contains the set of "VM helpers" which help to optimize monitors performance * in the code generated by JIT compiler. Typically, these functions will be called by JIT, * but VM also could also use them with care. - */ + */ #include #include -#include "../thread_private.h" #include "open/thread_externals.h" #include "open/jthread.h" @@ -40,17 +39,18 @@ * * @return tm_self() in eax register */ -char* gen_hythread_self_helper(char *ss) { +char *gen_hythread_self_helper(char *ss) +{ #ifdef FS14_TLS_USE //ss = mov(ss, eax_opnd, M_Base_Opnd(fs_reg, 0x14)); - *ss++ = (char)0x64; - *ss++ = (char)0xa1; - *ss++ = (char)0x14; - *ss++ = (char)0x00; - *ss++ = (char)0x00; - *ss++ = (char)0x00; + *ss++ = (char) 0x64; + *ss++ = (char) 0xa1; + *ss++ = (char) 0x14; + *ss++ = (char) 0x00; + *ss++ = (char) 0x00; + *ss++ = (char) 0x00; #else - ss = call(ss, (char *)hythread_self); + ss = call(ss, (char *) hythread_self); #endif return ss; } @@ -67,86 +67,92 @@ char* gen_hythread_self_helper(char *ss) { * * @return 0 if success in eax register */ -char* gen_monitorenter_fast_path_helper(char *ss, const R_Opnd & input_param1) { +char *gen_monitorenter_fast_path_helper(char *ss, const R_Opnd & input_param1) +{ if (&input_param1 != &ecx_opnd) { - ss = mov(ss, ecx_opnd, input_param1); + ss = mov(ss, ecx_opnd, input_param1); } #ifdef ASM_MONITOR_HELPER - signed offset2; + signed offset2; //get self_id ss = gen_hythread_self_helper(ss); - ss = mov(ss, edx_opnd, M_Base_Opnd(eax_reg, (uint32)&((HyThread *)0)->thread_id) ); + ss = mov(ss, edx_opnd, + M_Base_Opnd(eax_reg, hythread_get_thread_id_offset())); #ifdef LOCK_RESERVATION //get lock_id - ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, 0)); + ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, 0)); // move thread_id to AX - ss = shift(ss, ror_opc, eax_opnd, Imm_Opnd(16)); + ss = shift(ss, ror_opc, eax_opnd, Imm_Opnd(16)); // test this recursion call - ss = alu(ss, cmp_opc, edx_opnd, eax_opnd, size_16); - ss = branch8(ss, Condition_Z, Imm_Opnd(size_8, 0)); - char *backpatch_address__recursion_inc = ((char *)ss) - 1; + ss = alu(ss, cmp_opc, edx_opnd, eax_opnd, size_16); + ss = branch8(ss, Condition_Z, Imm_Opnd(size_8, 0)); + char *backpatch_address__recursion_inc = ((char *) ss) - 1; // test the lock is busy - ss = test(ss, eax_opnd, eax_opnd, size_16); - ss = branch8(ss, Condition_NZ, Imm_Opnd(size_8, 0)); - char *backpatch_address__inline_monitor_failed = ((char *)ss) - 1; + ss = test(ss, eax_opnd, eax_opnd, size_16); + ss = branch8(ss, Condition_NZ, Imm_Opnd(size_8, 0)); + char *backpatch_address__inline_monitor_failed = ((char *) ss) - 1; #else - ss = alu(ss, xor_opc, eax_opnd, eax_opnd); + ss = alu(ss, xor_opc, eax_opnd, eax_opnd); #endif // the lock is free or not reserved - ss = prefix(ss, lock_prefix); - ss = cmpxchg(ss, M_Base_Opnd(ecx_reg, 2), edx_opnd, size_16); - ss = branch8(ss, Condition_NZ, Imm_Opnd(size_8, 0)); - char *backpatch_address__inline_monitor_failed2 = ((char *)ss) - 1; + ss = prefix(ss, lock_prefix); + ss = cmpxchg(ss, M_Base_Opnd(ecx_reg, 2), edx_opnd, size_16); + ss = branch8(ss, Condition_NZ, Imm_Opnd(size_8, 0)); + char *backpatch_address__inline_monitor_failed2 = ((char *) ss) - 1; #ifdef LOCK_RESERVATION // if this is initial reservation also increase the recursion ss = mov(ss, edx_opnd, eax_opnd); // eax still ROR so ROR the mask - ss = alu(ss, and_opc, edx_opnd, Imm_Opnd(0x0400ffff)); - ss = test(ss, edx_opnd, edx_opnd); - ss = branch8(ss, Condition_Z, Imm_Opnd(size_8, 0)); - char *backpatch_address__recursion_inc2 = ((char *)ss) - 1; + ss = alu(ss, and_opc, edx_opnd, Imm_Opnd(0x0400ffff)); + ss = test(ss, edx_opnd, edx_opnd); + ss = branch8(ss, Condition_Z, Imm_Opnd(size_8, 0)); + char *backpatch_address__recursion_inc2 = ((char *) ss) - 1; #endif - ss = ret(ss, Imm_Opnd(4)); + ss = ret(ss, Imm_Opnd(4)); #ifdef LOCK_RESERVATION - // increase recursion branch - signed offset = (signed)ss - (signed)backpatch_address__recursion_inc - 1; - *backpatch_address__recursion_inc = (char)offset; - + // increase recursion branch + signed offset = + (signed) ss - (signed) backpatch_address__recursion_inc - 1; + *backpatch_address__recursion_inc = (char) offset; + // test recursion overflow // eax still ROR so ROR the mask - ss = alu(ss, cmp_opc, eax_opnd, Imm_Opnd(0xf4000000)); - ss = branch8(ss, Condition_A, Imm_Opnd(size_8, 0)); - char *backpatch_address__inline_monitor_failed3 = ((char *)ss) - 1; + ss = alu(ss, cmp_opc, eax_opnd, Imm_Opnd(0xf4000000)); + ss = branch8(ss, Condition_A, Imm_Opnd(size_8, 0)); + char *backpatch_address__inline_monitor_failed3 = ((char *) ss) - 1; - offset2 = (signed)ss - (signed)backpatch_address__recursion_inc2 - 1; - *backpatch_address__recursion_inc2 = (char)offset2; + offset2 = (signed) ss - (signed) backpatch_address__recursion_inc2 - 1; + *backpatch_address__recursion_inc2 = (char) offset2; // restore lock_id - ss = shift(ss, ror_opc, eax_opnd, Imm_Opnd(16)); - ss = alu(ss, add_opc, eax_opnd, Imm_Opnd(size_16, 0x800), size_16); - ss = mov(ss, M_Base_Opnd(ecx_reg, 0), eax_opnd, size_16); - - ss = ret(ss, Imm_Opnd(4)); - - offset = (signed)ss - (signed)backpatch_address__inline_monitor_failed - 1; - *backpatch_address__inline_monitor_failed = (char)offset; - offset = (signed)ss - (signed)backpatch_address__inline_monitor_failed3 - 1; - *backpatch_address__inline_monitor_failed3 = (char)offset; + ss = shift(ss, ror_opc, eax_opnd, Imm_Opnd(16)); + ss = alu(ss, add_opc, eax_opnd, Imm_Opnd(size_16, 0x800), size_16); + ss = mov(ss, M_Base_Opnd(ecx_reg, 0), eax_opnd, size_16); + + ss = ret(ss, Imm_Opnd(4)); + + offset = + (signed) ss - (signed) backpatch_address__inline_monitor_failed - 1; + *backpatch_address__inline_monitor_failed = (char) offset; + offset = + (signed) ss - (signed) backpatch_address__inline_monitor_failed3 - 1; + *backpatch_address__inline_monitor_failed3 = (char) offset; #endif - offset2 = (signed)ss - (signed)backpatch_address__inline_monitor_failed2 - 1; - *backpatch_address__inline_monitor_failed2 = (char)offset2; + offset2 = + (signed) ss - (signed) backpatch_address__inline_monitor_failed2 - 1; + *backpatch_address__inline_monitor_failed2 = (char) offset2; #endif //ASM_MONITOR_HELPER // the second attempt to lock monitor - ss = push(ss, ecx_opnd); - ss = call(ss, (char *)hythread_thin_monitor_try_enter); - ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters + ss = push(ss, ecx_opnd); + ss = call(ss, (char *) hythread_thin_monitor_try_enter); + ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters return ss; } @@ -162,14 +168,15 @@ char* gen_monitorenter_fast_path_helper(char *ss, const R_Opnd & input_param1) { * the code use and do not restore ecx, edx, eax registers * @return 0 if success in eax register */ -char* gen_monitorenter_slow_path_helper(char *ss, const R_Opnd & input_param1) { +char *gen_monitorenter_slow_path_helper(char *ss, const R_Opnd & input_param1) +{ if (&input_param1 != &eax_opnd) { - ss = mov(ss, eax_opnd, input_param1); + ss = mov(ss, eax_opnd, input_param1); } - ss = push(ss, eax_opnd); // push the address of the handle - ss = call(ss, (char *)jthread_monitor_enter); - ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters + ss = push(ss, eax_opnd); // push the address of the handle + ss = call(ss, (char *) jthread_monitor_enter); + ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters return ss; } @@ -183,41 +190,43 @@ char* gen_monitorenter_slow_path_helper(char *ss, const R_Opnd & input_param1) { * The code use and do not restore eax registers. * @return 0 if success in eax register */ -char* gen_monitor_exit_helper(char *ss, const R_Opnd & input_param1) { +char *gen_monitor_exit_helper(char *ss, const R_Opnd & input_param1) +{ if (&input_param1 != &ecx_opnd) { - ss = mov(ss, ecx_opnd, input_param1); + ss = mov(ss, ecx_opnd, input_param1); } #ifdef ASM_MONITOR_HELPER - ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, 0)); - ss = mov(ss, edx_opnd, eax_opnd); - ss = alu(ss, and_opc, eax_opnd, 0x8000f800); - ss = test(ss, eax_opnd, eax_opnd); - ss = branch8(ss, Condition_Z, Imm_Opnd(size_8, 0)); - char *backpatch_address__thin_monitor = ((char *)ss) - 1; - ss = alu(ss, and_opc, eax_opnd, 0x80000000); - ss = test(ss, eax_opnd, eax_opnd); - ss = branch8(ss, Condition_NZ, Imm_Opnd(size_8, 0)); - char *backpatch_address__fat_monitor = ((char *)ss) - 1; + ss = mov(ss, eax_opnd, M_Base_Opnd(ecx_reg, 0)); + ss = mov(ss, edx_opnd, eax_opnd); + ss = alu(ss, and_opc, eax_opnd, 0x8000f800); + ss = test(ss, eax_opnd, eax_opnd); + ss = branch8(ss, Condition_Z, Imm_Opnd(size_8, 0)); + char *backpatch_address__thin_monitor = ((char *) ss) - 1; + ss = alu(ss, and_opc, eax_opnd, 0x80000000); + ss = test(ss, eax_opnd, eax_opnd); + ss = branch8(ss, Condition_NZ, Imm_Opnd(size_8, 0)); + char *backpatch_address__fat_monitor = ((char *) ss) - 1; // recursion or reservation => dec recursion count - ss = alu(ss, sub_opc, edx_opnd, Imm_Opnd(0x800)); - ss = mov(ss, M_Base_Opnd(ecx_reg,0), edx_opnd); - ss = ret(ss, Imm_Opnd(4)); + ss = alu(ss, sub_opc, edx_opnd, Imm_Opnd(0x800)); + ss = mov(ss, M_Base_Opnd(ecx_reg, 0), edx_opnd); + ss = ret(ss, Imm_Opnd(4)); - signed offset = (signed)ss - (signed)backpatch_address__thin_monitor - 1; - *backpatch_address__thin_monitor = (char)offset; + signed offset = + (signed) ss - (signed) backpatch_address__thin_monitor - 1; + *backpatch_address__thin_monitor = (char) offset; ss = mov(ss, M_Base_Opnd(ecx_reg, 2), Imm_Opnd(size_16, 0), size_16); - ss = ret(ss, Imm_Opnd(4)); + ss = ret(ss, Imm_Opnd(4)); - offset = (signed)ss - (signed)backpatch_address__fat_monitor - 1; - *backpatch_address__fat_monitor = (char)offset; + offset = (signed) ss - (signed) backpatch_address__fat_monitor - 1; + *backpatch_address__fat_monitor = (char) offset; #endif - ss = push(ss, ecx_opnd); - ss = call(ss, (char *)hythread_thin_monitor_exit); - ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters + ss = push(ss, ecx_opnd); + ss = call(ss, (char *) hythread_thin_monitor_exit); + ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters return ss; } @@ -232,16 +241,17 @@ char* gen_monitor_exit_helper(char *ss, const R_Opnd & input_param1) { * the code use and do not restore ecx, edx, eax registers * @return 0 if success in eax register */ -char* gen_monitorexit_slow_path_helper(char *ss, const R_Opnd & input_param1) { - if (&input_param1 != &eax_opnd) { - ss = mov(ss, eax_opnd, input_param1); +char *gen_monitorexit_slow_path_helper(char *ss, const R_Opnd & input_param1) +{ + if (&input_param1 != &eax_opnd) { + ss = mov(ss, eax_opnd, input_param1); } - - ss = push(ss, eax_opnd); // push the address of the handle - ss = call(ss, (char *)jthread_monitor_exit); - ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters + + ss = push(ss, eax_opnd); // push the address of the handle + ss = call(ss, (char *) jthread_monitor_exit); + ss = alu(ss, add_opc, esp_opnd, Imm_Opnd(4)); // pop parameters return ss; -} +} /** * Generates fast accessor to the TLS for the given key.
@@ -255,21 +265,23 @@ char* gen_monitorexit_slow_path_helper(char *ss, const R_Opnd & input_param1) { * @param[in] key TLS key * @return fast accessor to key, if one exist */ -fast_tls_func* get_tls_helper(hythread_tls_key_t key) { +fast_tls_func *get_tls_helper(hythread_tls_key_t key) +{ // return tm_self_tls->thread_local_storage[key]; - unsigned key_offset = (unsigned)&(((HyThread_public*)(0))->thread_local_storage[key]); - + unsigned key_offset = + (unsigned) &(((HyThread_public *) (0))->thread_local_storage[key]); + const int stub_size = 126; - char *stub = (char *)malloc(stub_size); - memset(stub, 0xcc /*int 3*/, stub_size); + char *stub = (char *) malloc(stub_size); + memset(stub, 0xcc /*int 3 */ , stub_size); char *ss = stub; - + ss = gen_hythread_self_helper(ss); - ss = mov(ss, eax_opnd, M_Base_Opnd(eax_reg, key_offset)); - ss = ret(ss, Imm_Opnd(0)); + ss = mov(ss, eax_opnd, M_Base_Opnd(eax_reg, key_offset)); + ss = ret(ss, Imm_Opnd(0)); assert((ss - stub) < stub_size); - return (fast_tls_func*) stub; + return (fast_tls_func *) stub; } diff --git a/vm/vmcore/src/thread/helpers/thread_helpers_ipf.cpp b/vm/vmcore/src/thread/helpers/thread_helpers_ipf.cpp index 9f852c0..f17f5a4 100644 --- a/vm/vmcore/src/thread/helpers/thread_helpers_ipf.cpp +++ b/vm/vmcore/src/thread/helpers/thread_helpers_ipf.cpp @@ -18,7 +18,7 @@ /** * @file thread_helpers_ipf.c * Missing definition to ipf compile - */ + */ #include #include @@ -28,13 +28,14 @@ #include -void *dummy_tls_func() { +void *dummy_tls_func() +{ assert(0); abort(); } -fast_tls_func* get_tls_helper(hythread_tls_key_t key) { +fast_tls_func *get_tls_helper(hythread_tls_key_t key) +{ return dummy_tls_func; } - diff --git a/vm/vmcore/src/thread/lock_manager.cpp b/vm/vmcore/src/thread/lock_manager.cpp index 58b87dc..bd91ef6 100644 --- a/vm/vmcore/src/thread/lock_manager.cpp +++ b/vm/vmcore/src/thread/lock_manager.cpp @@ -24,10 +24,6 @@ #include "vm_threads.h" #include "exceptions.h" -//void vm_thread_enumerate_from_native(VM_thread *thread); // unused anywhere - -extern hythread_library_t hythread_lib; - Lock_Manager::Lock_Manager() { UNREF IDATA stat = hymutex_create (&lock, TM_MUTEX_NESTED); diff --git a/vm/vmcore/src/thread/thread_dump.cpp b/vm/vmcore/src/thread/thread_dump.cpp index 04c6ddf..58519f6 100644 --- a/vm/vmcore/src/thread/thread_dump.cpp +++ b/vm/vmcore/src/thread/thread_dump.cpp @@ -42,35 +42,28 @@ #include "cxxlog.h" -static std::set unique_references; +static std::set < void *>unique_references; -enum reference_types { +enum reference_types +{ root_reference = 1, compresses_root_reference, managed_reference, managed_reference_with_base }; - void td_print_thread_dumps(FILE* f); -#ifdef _DEBUG - void td_print_native_dumps(FILE* f); - #endif - void td_attach_thread(void( *printer)(FILE *), FILE *out); +void td_attach_thread(void (*printer) (FILE *), FILE * out); -VMEXPORT void vm_check_if_monitor(void **reference, - void **base_reference, - uint32 *compressed_reference, - int slotOffset, - Boolean pinned, - int type) { +VMEXPORT void vm_check_if_monitor(void **reference, + void **base_reference, + uint32 * compressed_reference, + int slotOffset, Boolean pinned, int type) +{ } /** * The thread dump entry poin, this function being called from the signal handler */ -void td_dump_all_threads(FILE *out) { -#ifdef _DEBUG -// td_print_native_dumps(out); -#endif - // td_attach_thread(td_print_thread_dumps, out); +void td_dump_all_threads(FILE * out) +{ } diff --git a/vm/vmcore/src/thread/thread_generic.cpp b/vm/vmcore/src/thread/thread_generic.cpp index 388dfa5..2a5ec2c 100644 --- a/vm/vmcore/src/thread/thread_generic.cpp +++ b/vm/vmcore/src/thread/thread_generic.cpp @@ -17,7 +17,7 @@ /** * @author Andrey Chernyshev * @version $Revision: 1.1.2.5.4.5 $ - */ + */ #define LOG_DOMAIN "thread" @@ -95,70 +95,74 @@ using namespace std; extern struct JNINativeInterface_ jni_vtable; -struct vmthread_dummies { +struct vmthread_dummies +{ VM_thread *p_vm_thread; ObjectHandles *p_object_handles; M2nFrame *p_m2n_frame; }; -void *vm_allocate_thread_dummies(JavaVM *java_vm) { +void *vm_allocate_thread_dummies(JavaVM * java_vm) +{ struct vmthread_dummies *p_vmt_dummies; - VM_thread *vmt = allocate_thread_block((JavaVM_Internal *)java_vm); - - if (vmt == NULL) - goto err; - - p_vmt_dummies = - (struct vmthread_dummies *)apr_palloc(vmt->pool, sizeof(vmthread_dummies)); - + VM_thread *vmt = allocate_thread_block((JavaVM_Internal *) java_vm); + + if (vmt == NULL) + goto err; + + p_vmt_dummies = + (struct vmthread_dummies *) apr_palloc(vmt->pool, + sizeof(vmthread_dummies)); + if (p_vmt_dummies == NULL) - goto err; - + goto err; + // Create top level M2N frame. - p_vmt_dummies->p_m2n_frame = - (M2nFrame*) apr_palloc(vmt->pool, sizeof(M2nFrame)); + p_vmt_dummies->p_m2n_frame = + (M2nFrame *) apr_palloc(vmt->pool, sizeof(M2nFrame)); // Create local handles. - p_vmt_dummies->p_object_handles = - (ObjectHandles*) apr_palloc(vmt->pool, sizeof(ObjectHandlesNew)); + p_vmt_dummies->p_object_handles = + (ObjectHandles *) apr_palloc(vmt->pool, sizeof(ObjectHandlesNew)); // allocate jni env internal structures - vmt->jni_env = (JNIEnv_Internal *) apr_palloc(vmt->pool, - sizeof(JNIEnv_Internal)); + vmt->jni_env = (JNIEnv_Internal *) apr_palloc(vmt->pool, + sizeof(JNIEnv_Internal)); if (vmt->jni_env == NULL || p_vmt_dummies->p_object_handles == NULL || - p_vmt_dummies->p_m2n_frame == NULL) - goto err; - + p_vmt_dummies->p_m2n_frame == NULL) + goto err; + p_vmt_dummies->p_vm_thread = vmt; - return (void*)p_vmt_dummies; + return (void *) p_vmt_dummies; - err: +err: if (p_vmt_dummies->p_m2n_frame) - free (p_vmt_dummies->p_m2n_frame); + free(p_vmt_dummies->p_m2n_frame); if (p_vmt_dummies->p_object_handles) - free(p_vmt_dummies->p_object_handles); + free(p_vmt_dummies->p_object_handles); if (vmt->jni_env) - free(vmt->jni_env); - if (p_vmt_dummies) - free(p_vmt_dummies); - if (vmt) - free(vmt); + free(vmt->jni_env); + if (p_vmt_dummies) + free(p_vmt_dummies); + if (vmt) + free(vmt); return NULL; } - + /** * Runs java.lang.Thread.detach() method. */ -static jint run_java_detach(jthread java_thread) { - static Method * detach = NULL; - const char * method_name = "detach"; - const char * descriptor = "(Ljava/lang/Throwable;)V"; +static jint run_java_detach(jthread java_thread) +{ + static Method *detach = NULL; + const char *method_name = "detach"; + const char *descriptor = "(Ljava/lang/Throwable;)V"; jvalue args[2]; - JNIEnv * jni_env; - Global_Env * vm_env; - Class * thread_class; + JNIEnv *jni_env; + Global_Env *vm_env; + Class *thread_class; assert(hythread_is_suspend_enabled()); @@ -169,18 +173,18 @@ static jint run_java_detach(jthread java_thread) { if (detach == NULL) { detach = class_lookup_method(thread_class, method_name, descriptor); if (detach == NULL) { - TRACE("Failed to find thread's detach method " << descriptor << " , exception = " << exn_get()); + TRACE("Failed to find thread's detach method " << descriptor << + " , exception = " << exn_get()); return TM_ERROR_INTERNAL; } } - // Initialize arguments. args[0].l = java_thread; if (vm_env->IsVmShutdowning()) { args[1].l = NULL; } else { args[1].l = exn_get(); - } + } exn_clear(); hythread_suspend_disable(); @@ -188,7 +192,9 @@ static jint run_java_detach(jthread java_thread) { hythread_suspend_enable(); if (exn_raised()) { - TRACE("java.lang.Thread.detach(Throwable) method completed with an exception: " << exn_get_name()); + TRACE + ("java.lang.Thread.detach(Throwable) method completed with an exception: " + << exn_get_name()); return TM_ERROR_INTERNAL; } return TM_ERROR_NONE; @@ -197,63 +203,66 @@ static jint run_java_detach(jthread java_thread) { /** * Attaches thread current thread to VM. */ -jint vm_attach(JavaVM * java_vm, JNIEnv ** p_jni_env, - void *pv_vmt_dummies) { - M2nFrame * p_m2n; - VM_thread * p_vm_thread; - ObjectHandles * p_handles; - struct vmthread_dummies *p_vmt_dummies = - (struct vmthread_dummies *)pv_vmt_dummies; +jint vm_attach(JavaVM * java_vm, JNIEnv ** p_jni_env, void *pv_vmt_dummies) +{ + M2nFrame *p_m2n; + VM_thread *p_vm_thread; + ObjectHandles *p_handles; + struct vmthread_dummies *p_vmt_dummies = + (struct vmthread_dummies *) pv_vmt_dummies; if (p_vmt_dummies != NULL) { - p_m2n = p_vmt_dummies->p_m2n_frame; - p_vm_thread = p_vmt_dummies->p_vm_thread; - p_handles = p_vmt_dummies->p_object_handles; + p_m2n = p_vmt_dummies->p_m2n_frame; + p_vm_thread = p_vmt_dummies->p_vm_thread; + p_handles = p_vmt_dummies->p_object_handles; } - // It seems to be reasonable to have suspend enabled state here. // It is unsafe to perform operations which require suspend disabled // mode until current thread is not attaced to VM. assert(hythread_is_suspend_enabled()); if (p_vmt_dummies != NULL) { - // VMThread structure is already allocated, we only need to set - // TLS - set_TLS_data (p_vm_thread); + // VMThread structure is already allocated, we only need to set + // TLS + set_TLS_data(p_vm_thread); } else { - p_vm_thread = get_vm_thread(hythread_self()); - - if (p_vm_thread != NULL) { - assert (java_vm == p_vm_thread->jni_env->vm); - *p_jni_env = p_vm_thread->jni_env; - return JNI_OK; - } - - p_vm_thread = get_a_thread_block((JavaVM_Internal *)java_vm); + p_vm_thread = get_vm_thread(hythread_self()); + + if (p_vm_thread != NULL) { + assert(java_vm == + ((JNIEnv_Internal *) (p_vm_thread->jni_env))->vm); + *p_jni_env = p_vm_thread->jni_env; + return JNI_OK; + } + + p_vm_thread = get_a_thread_block((JavaVM_Internal *) java_vm); } // if the assertion is false we cannot notify the parent thread // that we started and it would hang in waitloop - assert (p_vm_thread != NULL); - + assert(p_vm_thread != NULL); + if (p_vmt_dummies == NULL) { - // Create top level M2N frame. - p_m2n = (M2nFrame*) apr_palloc(p_vm_thread->pool, sizeof(M2nFrame)); - // Create local handles. - p_handles = (ObjectHandles*) apr_palloc(p_vm_thread->pool, sizeof(ObjectHandlesNew)); - p_vm_thread->jni_env = (JNIEnv_Internal *) apr_palloc(p_vm_thread->pool, sizeof(JNIEnv_Internal)); + // Create top level M2N frame. + p_m2n = (M2nFrame *) apr_palloc(p_vm_thread->pool, sizeof(M2nFrame)); + // Create local handles. + p_handles = + (ObjectHandles *) apr_palloc(p_vm_thread->pool, + sizeof(ObjectHandlesNew)); + p_vm_thread->jni_env = + (JNIEnv *) apr_palloc(p_vm_thread->pool, sizeof(JNIEnv_Internal)); } - assert (p_m2n != NULL && p_handles != NULL && p_vm_thread->jni_env != NULL); + assert(p_m2n != NULL && p_handles != NULL + && p_vm_thread->jni_env != NULL); // Initialize JNI environment. - p_vm_thread->jni_env->functions = &jni_vtable; - p_vm_thread->jni_env->vm = (JavaVM_Internal *)java_vm; - p_vm_thread->jni_env->reserved0 = (void *)0x1234abcd; - *p_jni_env = p_vm_thread->jni_env; + JNIEnv_Internal *jni_env = (JNIEnv_Internal *) p_vm_thread->jni_env; + jni_env->functions = &jni_vtable; + jni_env->vm = (JavaVM_Internal *) java_vm; + jni_env->reserved0 = (void *) 0x1234abcd; + *p_jni_env = jni_env; - - init_stack_info(); m2n_null_init(p_m2n); @@ -272,9 +281,10 @@ jint vm_attach(JavaVM * java_vm, JNIEnv ** p_jni_env, /** * Detaches current thread from VM. */ -jint vm_detach(jthread java_thread) { - VM_thread * p_vm_thread; - +jint vm_detach(jthread java_thread) +{ + VM_thread *p_vm_thread; + assert(hythread_is_suspend_enabled()); // could return error if detach throws an exception, @@ -301,7 +311,7 @@ jint vm_detach(jthread java_thread) { set_TLS_data(NULL); // Destroy current VM_thread structure. apr_pool_destroy(p_vm_thread->pool); - + hythread_suspend_enable(); return JNI_OK; @@ -320,14 +330,13 @@ jint vm_detach(jthread java_thread) { void vm_notify_obj_alive(void *p_obj) { - if (IS_FAT_LOCK(((ManagedObject *)p_obj)->get_obj_info())) { - uint32 xx = ((ManagedObject *)p_obj)->get_obj_info(); - hythread_native_resource_is_live(xx); + uint32 obj_info = ((ManagedObject*)p_obj)->get_obj_info(); + if (hythread_is_fat_lock(obj_info)) { + hythread_native_resource_is_live(obj_info); } } void vm_reclaim_native_objs() { - hythread_reclaim_resources(); + hythread_reclaim_resources(); } - diff --git a/vm/vmcore/src/thread/thread_java_attrs.cpp b/vm/vmcore/src/thread/thread_java_attrs.cpp index 2005e2c..a54ef3d 100644 --- a/vm/vmcore/src/thread/thread_java_attrs.cpp +++ b/vm/vmcore/src/thread/thread_java_attrs.cpp @@ -18,11 +18,11 @@ /** * @file thread_java_attrs.c * @brief Java thread priority related functions - */ + */ #include #include -#include "thread_private.h" +#include "vm_threads.h" /** * Returns the priority for the thread. @@ -30,7 +30,8 @@ * @param[in] java_thread thread those attribute is read * @sa java.lang.Thread.getPriority() */ -int jthread_get_priority(jthread java_thread) { +int jthread_get_priority(jthread java_thread) +{ hythread_t tm_native_thread = jthread_get_native_thread(java_thread); return hythread_get_priority(tm_native_thread); } @@ -42,7 +43,8 @@ int jthread_get_priority(jthread java_thread) { * @param[in] priority thread priority * @sa java.lang.Thread.setPriority() */ -IDATA VMCALL jthread_set_priority(jthread java_thread, int priority) { +IDATA VMCALL jthread_set_priority(jthread java_thread, int priority) +{ hythread_t tm_native_thread = jthread_get_native_thread(java_thread); return hythread_set_priority(tm_native_thread, priority); } @@ -52,9 +54,9 @@ IDATA VMCALL jthread_set_priority(jthread java_thread, int priority) { * * @param[in] thread thread those attribute is read */ -jboolean jthread_is_daemon(jthread thread) { - jvmti_thread_t jvmti_thread; - - jvmti_thread = (jvmti_thread_t)hythread_get_private_data(hythread_self()); +jboolean jthread_is_daemon(jthread thread) +{ + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(hythread_self()); return jvmti_thread->daemon; } diff --git a/vm/vmcore/src/thread/thread_java_basic.cpp b/vm/vmcore/src/thread/thread_java_basic.cpp index 051f959..b82ed04 100644 --- a/vm/vmcore/src/thread/thread_java_basic.cpp +++ b/vm/vmcore/src/thread/thread_java_basic.cpp @@ -22,34 +22,27 @@ #include #include -#include #include "open/thread_externals.h" -#include "open/vm.h" - -#undef LOG_DOMAIN -#define LOG_DOMAIN "tm.java" - -#include "thread_private.h" +#include "vm_threads.h" #include "jni.h" +#define LOG_DOMAIN "tm.java" +#include "cxxlog.h" +static jmethodID jthread_get_run_method(JNIEnv * env, jthread java_thread); +static IDATA jthread_associate_native_and_java_thread(JNIEnv * env, + jthread java_thread, hythread_t native_thread, jobject thread_ref); -void stop_callback(void); -jmethodID getRunMethod(JNIEnv *env, jthread java_thread); -IDATA increase_nondaemon_threads_count(hythread_t self); -IDATA countdown_nondaemon_threads(hythread_t self); - -typedef struct { - JavaVM * java_vm; +struct wrapper_proc_data +{ + JavaVM *java_vm; jboolean daemon; jvmtiEnv *tiEnv; jvmtiStartFunction tiProc; void *tiProcArgs; void *vm_thread_dummies; -} wrapper_proc_data; - - -IDATA associate_native_and_java_thread(JNIEnv* env, jthread java_thread, hythread_t tm_native_thread, jobject thread_ref); +}; +typedef struct wrapper_proc_data * wrapper_data_t; /** * Creates new Java thread. @@ -62,56 +55,58 @@ IDATA associate_native_and_java_thread(JNIEnv* env, jthread java_thread, hythrea * @param[in] attrs thread attributes. * @sa java.lang.Thread.run() */ -IDATA jthread_create(JNIEnv * jni_env, jthread java_thread, jthread_threadattr_t *attrs) { +IDATA jthread_create(JNIEnv *jni_env, + jthread java_thread, + jthread_threadattr_t *attrs) +{ + return jthread_create_with_function(jni_env, java_thread, + attrs, NULL, NULL); +} // jthread_create - return jthread_create_with_function(jni_env, java_thread, attrs, NULL, NULL); -} +static IDATA HYTHREAD_PROC jthread_wrapper_proc(void *arg) +{ + wrapper_data_t data = (wrapper_data_t) arg; -int wrapper_proc(void *arg) { - IDATA status; - JNIEnv * jni_env; - hythread_t native_thread; - jvmti_thread_t jvmti_thread; - jthread java_thread; - wrapper_proc_data *data = (wrapper_proc_data *)arg; - // Association should be already done. - native_thread = hythread_self(); - jvmti_thread = (jvmti_thread_t)hythread_get_private_data(native_thread); + hythread_t native_thread = hythread_self(); + jvmti_thread_t jvmti_thread = (jvmti_thread_t) hythread_get_private_data(native_thread); assert(jvmti_thread); - java_thread = jvmti_thread->thread_object; + jthread java_thread = jvmti_thread->thread_object; - status = vm_attach(data->java_vm, &jni_env, data->vm_thread_dummies); - assert (status == JNI_OK); + JNIEnv *jni_env; + IDATA status = vm_attach(data->java_vm, &jni_env, data->vm_thread_dummies); + assert(status == JNI_OK); jvmti_thread->jenv = jni_env; jvmti_thread->daemon = data->daemon; - TRACE( ("TM: Java thread started: id=%d OS_handle=%p", native_thread->thread_id, apr_os_thread_current()) ); + TRACE(("TM: Java thread started: id=%d OS_handle=%p", + hythread_get_id(native_thread), apr_os_thread_current())); if (!jvmti_thread->daemon) { - increase_nondaemon_threads_count(native_thread); + status = hythread_increase_nondaemon_threads_count(native_thread); + assert(status == TM_ERROR_NONE); } // Send Thread Start event. jvmti_send_thread_start_end_event(1); - - thread_start_count(); - + jthread_start_count(); if (data->tiProc != NULL) { data->tiProc(data->tiEnv, jni_env, data->tiProcArgs); } else { // for jthread_create(); - jni_env->CallVoidMethodA(java_thread, getRunMethod(jni_env, java_thread), NULL); + jni_env->CallVoidMethodA(java_thread, + jthread_get_run_method(jni_env, java_thread), NULL); } - + status = jthread_detach(java_thread); - TRACE(("TM: Java thread finished: id=%d OS_handle=%p", native_thread->thread_id, apr_os_thread_current())); + TRACE(("TM: Java thread finished: id=%d OS_handle=%p", + hythread_get_id(native_thread), apr_os_thread_current())); return status; -} +} // jthread_wrapper_proc /** * Creates new Java thread with specific execution function. @@ -129,71 +124,71 @@ int wrapper_proc(void *arg) { * @param[in] arg The argument to the start function. Is passed as an array. * @sa JVMTI::RunAgentThread() */ -IDATA jthread_create_with_function(JNIEnv * jni_env, jthread java_thread, jthread_threadattr_t *attrs, jvmtiStartFunction proc, const void* arg) +IDATA jthread_create_with_function(JNIEnv *jni_env, + jthread java_thread, + jthread_threadattr_t *attrs, + jvmtiStartFunction proc, + const void *arg) { - hythread_t tm_native_thread = NULL; - jvmti_thread_t tm_java_thread; - void *vm_thread_dummies; - static int default_stacksize = -1; - - wrapper_proc_data * data; - IDATA status; - if (jni_env == NULL || java_thread == NULL || attrs == NULL) { return TM_ERROR_NULL_POINTER; } - tm_native_thread = vm_jthread_get_tm_data(java_thread); - + hythread_t native_thread = vm_jthread_get_tm_data(java_thread); + // This is for irregular use. In ordinary live valid jthread instance // contains weak reference associated with it and native thread to reuse. - if (tm_native_thread == NULL) { - if ( !jthread_thread_init(NULL, jni_env, java_thread, NULL, 0)) { + if (native_thread == NULL) { + if (!jthread_thread_init(jni_env, java_thread, NULL, 0)) { return TM_ERROR_OUT_OF_MEMORY; } - tm_native_thread = vm_jthread_get_tm_data(java_thread); + native_thread = vm_jthread_get_tm_data(java_thread); } - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - assert(tm_java_thread); - tm_java_thread->thread_object = jni_env->NewGlobalRef(java_thread); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + assert(jvmti_thread); + jvmti_thread->thread_object = jni_env->NewGlobalRef(java_thread); - data = (wrapper_proc_data*)apr_palloc(tm_java_thread->pool, sizeof(wrapper_proc_data)); + wrapper_data_t data = + (wrapper_data_t)apr_palloc(jvmti_thread->pool, + sizeof(wrapper_proc_data)); if (data == NULL) { return TM_ERROR_OUT_OF_MEMORY; } - // Get JavaVM - status = jni_env->GetJavaVM(&data->java_vm); - if (status != JNI_OK) return TM_ERROR_INTERNAL; + IDATA status = jni_env->GetJavaVM(&data->java_vm); + if (status != JNI_OK) { + return TM_ERROR_INTERNAL; + } // Allocate memory needed by soon to be born thread - vm_thread_dummies = vm_allocate_thread_dummies(data->java_vm); - + void *vm_thread_dummies = vm_allocate_thread_dummies(data->java_vm); if (vm_thread_dummies == NULL) { - return TM_ERROR_OUT_OF_MEMORY; + return TM_ERROR_OUT_OF_MEMORY; } - if (default_stacksize == -1) { - int ss = get_size_property("thread.stacksize", 0, VM_PROPERTIES); - default_stacksize = ss ? ss : HY_DEFAULT_STACKSIZE; + static size_t default_stacksize; + if (0 == default_stacksize) { + size_t stack_size = get_size_property("thread.stacksize", 0, VM_PROPERTIES); + default_stacksize = stack_size ? stack_size : TM_DEFAULT_STACKSIZE; } - - // prepare args for wrapper_proc data->daemon = attrs->daemon; - data->tiEnv = attrs->jvmti_env; + data->tiEnv = attrs->jvmti_env; data->tiProc = proc; - data->tiProcArgs = (void *)arg; + data->tiProcArgs = (void *) arg; data->vm_thread_dummies = vm_thread_dummies; - status = hythread_create(&tm_native_thread, (attrs->stacksize)?attrs->stacksize:default_stacksize, - attrs->priority, 0, (hythread_entrypoint_t)wrapper_proc, data); + status = + hythread_create(&native_thread, + (attrs->stacksize ? attrs->stacksize : default_stacksize), + attrs->priority, 0, jthread_wrapper_proc, data); - TRACE(("TM: Created thread: id=%d", tm_native_thread->thread_id)); + TRACE(("TM: Created thread: id=%d", hythread_get_id(native_thread))); return status; -} +} // jthread_create_with_function /** * Attaches the current native thread to Java VM. @@ -207,73 +202,77 @@ IDATA jthread_create_with_function(JNIEnv * jni_env, jthread java_thread, jthrea * @param[in] daemon JNI_TRUE if attaching thread is a daemon thread, JNI_FALSE otherwise * @sa JNI::AttachCurrentThread () */ -IDATA jthread_attach(JNIEnv * jni_env, jthread java_thread, jboolean daemon) { - hythread_t tm_native_thread; - jvmti_thread_t jvmti_thread; - IDATA status; - - // Do nothing if thread already attached. - if (jthread_self() != NULL) return TM_ERROR_NONE; - - tm_native_thread = hythread_self(); - assert(tm_native_thread); +IDATA jthread_attach(JNIEnv *jni_env, jthread java_thread, jboolean daemon) +{ + if (jthread_self() != NULL) { + // Do nothing if thread already attached. + return TM_ERROR_NONE; + } - status = associate_native_and_java_thread(jni_env, java_thread, tm_native_thread, NULL); - if (status != TM_ERROR_NONE) return status; + hythread_t native_thread = hythread_self(); + assert(native_thread); + IDATA status = jthread_associate_native_and_java_thread(jni_env, java_thread, + native_thread, NULL); + if (status != TM_ERROR_NONE) { + return status; + } - jvmti_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); assert(jvmti_thread); jvmti_thread->thread_object = jni_env->NewGlobalRef(java_thread); jvmti_thread->jenv = jni_env; jvmti_thread->daemon = daemon; - - if (!jvmti_thread->daemon) { - increase_nondaemon_threads_count(tm_native_thread); + if (!daemon) { + status = hythread_increase_nondaemon_threads_count(native_thread); + assert(status == TM_ERROR_NONE); } // Send Thread Start event. jvmti_send_thread_start_end_event(1); - - thread_start_count(); + jthread_start_count(); TRACE(("TM: Current thread attached to jthread=%p", java_thread)); return TM_ERROR_NONE; -} +} // jthread_attach /** * Associates the Java thread with the native thread. * - * @param[in] ret_thread not used * @param[in] env JNI environment that will be associated with the created Java thread * @param[in] java_thread the Java thread for the association * @param[in] weak_ref java.lang.WeakReference to the java_thread that used for native resource deletion - * @param[in] old_thread the native thread for the association + * @param[in] dead_thread the native thread for the association * @return the native thread */ -jlong jthread_thread_init(jvmti_thread_t *ret_thread, JNIEnv* env, jthread java_thread, jobject weak_ref, jlong old_thread) { - hythread_t tm_native_thread = NULL; - jvmti_thread_t tmj_thread; - IDATA status; - - if (old_thread) { - tm_native_thread = (hythread_t)((IDATA)old_thread); - tmj_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); +jlong jthread_thread_init(JNIEnv *env, + jthread java_thread, + jobject weak_ref, + hythread_t dead_thread) +{ + hythread_t native_thread = NULL; + if (dead_thread) { + native_thread = (hythread_t) ((IDATA) dead_thread); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(dead_thread); //delete used weak reference - if (tmj_thread->thread_ref) - env->DeleteGlobalRef(tmj_thread->thread_ref); + if (jvmti_thread->thread_ref) { + env->DeleteGlobalRef(jvmti_thread->thread_ref); + } } - status = hythread_struct_init(&tm_native_thread); + IDATA status = hythread_struct_init(&native_thread); if (status != TM_ERROR_NONE) { return 0; } - - status = associate_native_and_java_thread(env, java_thread, tm_native_thread, weak_ref); + + status = jthread_associate_native_and_java_thread(env, java_thread, + native_thread, weak_ref); if (status != TM_ERROR_NONE) { return 0; } - return (jlong)((IDATA)tm_native_thread); -} + return (jlong)((IDATA)native_thread); +} // jthread_thread_init /** * Detaches the selected thread from java VM. @@ -282,89 +281,99 @@ jlong jthread_thread_init(jvmti_thread_t *ret_thread, JNIEnv* env, jthread java_ * * @param[in] java_thread Java thread to be detached */ -IDATA jthread_detach(jthread java_thread) { - IDATA status; - hythread_t tm_native_thread; - jvmti_thread_t tm_jvmti_thread; - JNIEnv * jni_env; - - assert(hythread_is_suspend_enabled()); - +IDATA jthread_detach(jthread java_thread) +{ // Check input arg assert(java_thread); + assert(hythread_is_suspend_enabled()); + TRACE(("TM: jthread_detach %x", hythread_self())); - tm_native_thread = jthread_get_native_thread(java_thread); - tm_jvmti_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - jni_env = tm_jvmti_thread->jenv; + hythread_t native_thread = jthread_get_native_thread(java_thread); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t)hythread_get_private_data(native_thread); + JNIEnv *jni_env = jvmti_thread->jenv; - if (!tm_jvmti_thread->daemon) { - countdown_nondaemon_threads(tm_native_thread); + IDATA status; + if (!jvmti_thread->daemon) { + status = hythread_decrease_nondaemon_threads_count(native_thread, 1); + assert(status == TM_ERROR_NONE); } // Detach from VM. status = vm_detach(java_thread); - if (status != JNI_OK) return TM_ERROR_INTERNAL; + if (status != JNI_OK) { + return TM_ERROR_INTERNAL; + } // Delete global reference to current thread object. - jni_env->DeleteGlobalRef(tm_jvmti_thread->thread_object); + jni_env->DeleteGlobalRef(jvmti_thread->thread_object); // jthread_self() will return NULL now. - tm_jvmti_thread->thread_object = NULL; + jvmti_thread->thread_object = NULL; // Decrease alive thread counter - thread_end_count(); - - // Deallocate tm_jvmti_thread - //apr_pool_destroy(tm_jvmti_thread->pool); - + jthread_end_count(); assert(hythread_is_suspend_enabled()); - return TM_ERROR_NONE; -} -IDATA associate_native_and_java_thread(JNIEnv * jni_env, jthread java_thread, hythread_t tm_native_thread, jobject thread_ref) + return TM_ERROR_NONE; +} // jthread_detach + +static IDATA +jthread_associate_native_and_java_thread(JNIEnv * jni_env, + jthread java_thread, + hythread_t native_thread, + jobject thread_ref) { - IDATA status; - apr_status_t apr_status; - apr_pool_t *pool; - jvmti_thread_t tm_java_thread; - - if ((jni_env == NULL) || (java_thread == NULL) || (tm_native_thread == NULL)) { + if ((jni_env == NULL) || (java_thread == NULL) + || (native_thread == NULL)) { return TM_ERROR_NULL_POINTER; } - - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - if (!tm_java_thread) { - apr_status = apr_pool_create(&pool, 0); - if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status); - if (pool == NULL) return TM_ERROR_OUT_OF_MEMORY; - tm_java_thread = (jvmti_thread_t)apr_palloc(pool, sizeof(JVMTIThread)); - if (tm_java_thread == NULL) return TM_ERROR_OUT_OF_MEMORY; - - tm_java_thread->pool = pool; - status = hythread_set_private_data(tm_native_thread, tm_java_thread); - if (status != TM_ERROR_NONE) return status; + jvmti_thread_t jvmti_thread = + (jvmti_thread_t)hythread_get_private_data(native_thread); + + if (!jvmti_thread) { + // init JVMTI data in native thread + apr_pool_t *pool; + apr_status_t apr_status = apr_pool_create(&pool, 0); + if (apr_status != APR_SUCCESS) { + return CONVERT_ERROR(apr_status); + } + if (pool == NULL) { + return TM_ERROR_OUT_OF_MEMORY; + } + jvmti_thread = (jvmti_thread_t)apr_palloc(pool, sizeof(JVMTIThread)); + if (jvmti_thread == NULL) { + return TM_ERROR_OUT_OF_MEMORY; + } + jvmti_thread->pool = pool; + IDATA status = hythread_set_private_data(native_thread, jvmti_thread); + if (status != TM_ERROR_NONE) { + return status; + } } - // JNI environment is created when this thread attaches to VM. - tm_java_thread->jenv = NULL; - tm_java_thread->thread_ref = (thread_ref) - ? jni_env->NewGlobalRef(thread_ref) : NULL; - tm_java_thread->contended_monitor = 0; - tm_java_thread->wait_monitor = 0; - tm_java_thread->blocked_count = 0; - tm_java_thread->blocked_time = 0; - tm_java_thread->waited_count = 0; - tm_java_thread->waited_time = 0; - tm_java_thread->owned_monitors = 0; - tm_java_thread->owned_monitors_nmb = 0; - tm_java_thread->jvmti_local_storage.env = 0; - tm_java_thread->jvmti_local_storage.data = 0; + + // init JVMTIThread structure + jvmti_thread->jenv = NULL; // JNI environment is created + // when this thread attaches to VM. + jvmti_thread->thread_ref = + (thread_ref) ? jni_env->NewGlobalRef(thread_ref) : NULL; + jvmti_thread->contended_monitor = 0; + jvmti_thread->wait_monitor = 0; + jvmti_thread->blocked_count = 0; + jvmti_thread->blocked_time = 0; + jvmti_thread->waited_count = 0; + jvmti_thread->waited_time = 0; + jvmti_thread->owned_monitors = 0; + jvmti_thread->owned_monitors_nmb = 0; + jvmti_thread->jvmti_local_storage.env = 0; + jvmti_thread->jvmti_local_storage.data = 0; // Associate java_thread with tm_thread - vm_jthread_set_tm_data(java_thread, tm_native_thread); - + vm_jthread_set_tm_data(java_thread, native_thread); + return TM_ERROR_NONE; -} +} // jthread_associate_native_and_java_thread /** * Waits till the thread is finished. @@ -374,19 +383,23 @@ IDATA associate_native_and_java_thread(JNIEnv * jni_env, jthread java_thread, hy * was successfully joined. * @sa java.lang.Thread.join() */ -IDATA jthread_join(jthread java_thread) { - IDATA status; - hythread_t tm_native_thread; - +IDATA jthread_join(jthread java_thread) +{ if (java_thread == NULL) { return TM_ERROR_NULL_POINTER; } - tm_native_thread = jthread_get_native_thread(java_thread); - status = hythread_join_interruptable(tm_native_thread, 0, 0); - TRACE(("TM: jthread %d joined %d", hythread_self()->thread_id, tm_native_thread->thread_id)); + hythread_t native_thread = jthread_get_native_thread(java_thread); + if (!native_thread) { + return TM_ERROR_NONE; + } + IDATA status = hythread_join_interruptable(native_thread, 0, 0); + + TRACE(("TM: jthread %d joined %d", hythread_get_id(hythread_self()), + hythread_get_id(native_thread))); + return status; -} +} // jthread_join /** * Waits till the thread is finished with specific timeout. @@ -398,48 +411,47 @@ IDATA jthread_join(jthread java_thread) { * was successfully joined. * @sa java.lang.Thread.join() */ -IDATA jthread_timed_join(jthread java_thread, jlong millis, jint nanos) { - - hythread_t tm_native_thread; - IDATA status; - +IDATA jthread_timed_join(jthread java_thread, jlong millis, jint nanos) +{ if (java_thread == NULL) { return TM_ERROR_NULL_POINTER; } - tm_native_thread = jthread_get_native_thread(java_thread); - if (!tm_native_thread) { - return TM_ERROR_NONE; + + hythread_t native_thread = jthread_get_native_thread(java_thread); + if (!native_thread) { + return TM_ERROR_NONE; } - status = hythread_join_interruptable(tm_native_thread, millis, nanos); - TRACE(("TM: jthread %d joined %d", hythread_self()->thread_id, tm_native_thread->thread_id)); + IDATA status = hythread_join_interruptable(native_thread, millis, nanos); + + TRACE(("TM: jthread %d joined %d", hythread_get_self_id(), + hythread_get_id(native_thread))); return status; -} +} // jthread_timed_join /** * Lets an another thread to pass. * @sa java.lang.Thread.yield() */ -IDATA jthread_yield() { +IDATA jthread_yield() +{ hythread_yield(); return TM_ERROR_NONE; -} +} // jthread_yield /* * Callback which is executed in the target thread at safe point * whenever Thread.stop() method is called. */ -void stop_callback(void) { - hythread_t tm_native_thread; - jvmti_thread_t tm_java_thread; - jobject excn; - - tm_native_thread = hythread_self(); - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - excn = tm_java_thread->stop_exception; - +static void stop_callback(void) +{ + hythread_t native_thread = hythread_self(); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + jobject excn = jvmti_thread->stop_exception; + jthread_throw_exception_object(excn); -} +} // stop_callback /** * Stops the execution of the given thread and forces @@ -448,21 +460,16 @@ void stop_callback(void) { * @param[in] java_thread thread to be stopped * @sa java.lang.Thread.stop() */ -IDATA jthread_stop(jthread java_thread) { - jclass clazz; - jmethodID excn_constr; - jobject excen_obj; - JNIEnv *env; - jvmti_thread_t tm_java_thread; - hythread_t tm_native_thread; - - tm_native_thread = vm_jthread_get_tm_data(java_thread); - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - env = tm_java_thread->jenv; - clazz = env->FindClass("java/lang/ThreadDeath"); - excn_constr = env->GetMethodID(clazz, "", "()V"); - excen_obj = env->NewObject(clazz, excn_constr); - +IDATA jthread_stop(jthread java_thread) +{ + hythread_t native_thread = vm_jthread_get_tm_data(java_thread); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + JNIEnv *env = jvmti_thread->jenv; + jclass clazz = env->FindClass("java/lang/ThreadDeath"); + jmethodID excn_constr = env->GetMethodID(clazz, "", "()V"); + jobject excen_obj = env->NewObject(clazz, excn_constr); + return jthread_exception_stop(java_thread, excen_obj); } @@ -474,43 +481,18 @@ IDATA jthread_stop(jthread java_thread) { * @param[in] excn exception to be thrown * @sa java.lang.Thread.stop() */ -IDATA jthread_exception_stop(jthread java_thread, jobject excn) { - - jvmti_thread_t tm_java_thread; - hythread_t tm_native_thread; - JNIEnv* env; - IDATA res; +IDATA jthread_exception_stop(jthread java_thread, jobject excn) +{ + hythread_t native_thread = jthread_get_native_thread(java_thread); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); - tm_native_thread = jthread_get_native_thread(java_thread); - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - // Install safepoint callback that would throw exception - env = jthread_get_JNI_env(jthread_self()); - tm_java_thread->stop_exception = env->NewGlobalRef(excn); - - res = hythread_set_safepoint_callback(tm_native_thread, stop_callback); + JNIEnv *env = jthread_get_JNI_env(jthread_self()); + jvmti_thread->stop_exception = env->NewGlobalRef(excn); - while (tm_native_thread->suspend_count > 0) { - apr_atomic_dec32((volatile apr_uint32_t *)&tm_native_thread->suspend_count); - apr_atomic_dec32((volatile apr_uint32_t *)&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 - // if safepoint callback isn't set it could be equal to 0. - // - // The following assertion may be false because at each time - // one of the conditions is true, and the other is false, but - // when checking the whole condition it may be failse in the result. - // assert(tm_native_thread->request > 0 || tm_native_thread->safepoint_callback == NULL); - - // 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; -} + return hythread_set_thread_stop_callback(native_thread, stop_callback); +} // jthread_exception_stop /** * Causes the current thread to sleep for at least the specified time. @@ -523,28 +505,36 @@ IDATA jthread_exception_stop(jthread java_thread, jobject excn) { * or TM_THREAD_INTERRUPTED in case thread was interrupted during sleep. * @sa java.lang.Thread.sleep() */ -IDATA jthread_sleep(jlong millis, jint nanos) { - - hythread_t tm_native_thread = hythread_self(); - IDATA status; - - tm_native_thread->state &= ~TM_THREAD_STATE_RUNNABLE; - tm_native_thread->state |= TM_THREAD_STATE_WAITING | TM_THREAD_STATE_SLEEPING | - TM_THREAD_STATE_WAITING_WITH_TIMEOUT; +IDATA jthread_sleep(jlong millis, jint nanos) +{ + hythread_t native_thread = hythread_self(); + hythread_thread_lock(native_thread); + IDATA state = hythread_get_state(native_thread); + state &= ~TM_THREAD_STATE_RUNNABLE; + state |= TM_THREAD_STATE_WAITING | TM_THREAD_STATE_SLEEPING + | TM_THREAD_STATE_WAITING_WITH_TIMEOUT; + IDATA status = hythread_set_state(native_thread, state); + assert(status == TM_ERROR_NONE); + hythread_thread_unlock(native_thread); - status = hythread_sleep_interruptable(millis, nanos); + status = hythread_sleep_interruptable(millis, nanos); #ifndef NDEBUG if (status == TM_ERROR_INTERRUPT) { - TRACE(("TM: sleep interrupted status received, thread: %p", hythread_self())); + TRACE(("TM: sleep interrupted status received, thread: %p", + hythread_self())); } #endif - - tm_native_thread->state &= ~(TM_THREAD_STATE_WAITING | TM_THREAD_STATE_SLEEPING | - TM_THREAD_STATE_WAITING_WITH_TIMEOUT); - tm_native_thread->state |= TM_THREAD_STATE_RUNNABLE; + hythread_thread_lock(native_thread); + state = hythread_get_state(native_thread); + state &= ~(TM_THREAD_STATE_WAITING | TM_THREAD_STATE_SLEEPING + | TM_THREAD_STATE_WAITING_WITH_TIMEOUT); + state |= TM_THREAD_STATE_RUNNABLE; + hythread_set_state(native_thread, state); + hythread_thread_unlock(native_thread); + return status; -} +} // jthread_sleep /** * Returns JNI environment associated with the given jthread, or NULL if there is none. @@ -554,25 +544,25 @@ IDATA jthread_sleep(jlong millis, jint nanos) { * * @param[in] java_thread java.lang.Thread object */ -JNIEnv *jthread_get_JNI_env(jthread java_thread) { - hythread_t tm_native_thread; - jvmti_thread_t tm_java_thread; - +JNIEnv * jthread_get_JNI_env(jthread java_thread) +{ if (java_thread == NULL) { return NULL; } - tm_native_thread = jthread_get_native_thread(java_thread); - if (tm_native_thread == NULL) { + hythread_t native_thread = jthread_get_native_thread(java_thread); + if (native_thread == NULL) { return NULL; } - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - if (tm_java_thread == NULL) { + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + if (jvmti_thread == NULL) { return NULL; } - return tm_java_thread->jenv; -} + return jvmti_thread->jenv; +} // jthread_get_JNI_env + /** - * Returns thread Id for the given thread. + * Returns thread ID for the given thread. * * Thread ID must be unique for all Java threads. * Can be reused after thread is finished. @@ -580,15 +570,12 @@ JNIEnv *jthread_get_JNI_env(jthread java_thread) { * @return thread ID * @sa java.lang.Thread.getId() */ -jlong jthread_get_id(jthread java_thread) { - - hythread_t tm_native_thread; - - tm_native_thread = jthread_get_native_thread(java_thread); - assert(tm_native_thread); - - return hythread_get_id(tm_native_thread); -} +jlong jthread_get_id(jthread java_thread) +{ + hythread_t native_thread = jthread_get_native_thread(java_thread); + assert(native_thread); + return hythread_get_id(native_thread); +} // jthread_get_id /** * Returns jthread given the thread ID. @@ -596,187 +583,106 @@ jlong jthread_get_id(jthread java_thread) { * @param[in] thread_id thread ID * @return jthread for the given ID, or NULL if there are no such. */ -jthread jthread_get_thread(jlong thread_id) { - - hythread_t tm_native_thread; - jvmti_thread_t tm_java_thread; - jthread java_thread; - - tm_native_thread = hythread_get_thread((jint)thread_id); - if (tm_native_thread == NULL) { +jthread jthread_get_thread(jlong thread_id) +{ + hythread_t native_thread = hythread_get_thread((IDATA)thread_id); + if (native_thread == NULL) { return NULL; } - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - java_thread = tm_java_thread->thread_object; + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + jthread java_thread = jvmti_thread->thread_object; assert(java_thread); return java_thread; -} +} // jthread_get_thread /** * Returns native thread associated with the given Java thread. * * @return native thread */ -hythread_t jthread_get_native_thread(jthread thread) { - +hythread_t jthread_get_native_thread(jthread thread) +{ assert(thread); - return vm_jthread_get_tm_data(thread); -} + return vm_jthread_get_tm_data(thread); +} // jthread_get_native_thread /** * Returns Java thread associated with the given native thread. * * @return Java thread */ -jthread jthread_get_java_thread(hythread_t tm_native_thread) { - - jvmti_thread_t tm_java_thread; - - if (tm_native_thread == NULL) { +jthread jthread_get_java_thread(hythread_t native_thread) +{ + if (native_thread == NULL) { TRACE(("TM: native thread is NULL")); return NULL; } - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - - if (tm_java_thread == NULL) { - TRACE(("TM: tmj thread is NULL")); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + if (jvmti_thread == NULL) { + TRACE(("TM: jvmti_thread_t thread is NULL")); return NULL; } + return jvmti_thread->thread_object; +} // jthread_get_java_thread - return tm_java_thread->thread_object; -} /** * Returns jthread associated with the current thread. * * @return jthread associated with the current thread, * or NULL if the current native thread is not attached to JVM. */ -jthread jthread_self(void) { +jthread jthread_self(void) +{ return jthread_get_java_thread(hythread_self()); -} +} // jthread_self /** * Cancels all java threads. This method being used at VM shutdown * to terminate all java threads. - */ -IDATA jthread_cancel_all() { + */ +IDATA jthread_cancel_all() +{ return hythread_cancel_all(NULL); -} +} // jthread_cancel_all /** * waiting all nondaemon thread's * */ -IDATA VMCALL jthread_wait_for_all_nondaemon_threads() { - hythread_t native_thread; - jvmti_thread_t jvmti_thread; - hythread_library_t lib; - IDATA status; - - native_thread = hythread_self(); - jvmti_thread = (jvmti_thread_t)hythread_get_private_data(native_thread); - lib = native_thread->library; - - status = hymutex_lock(&lib->TM_LOCK); - if (status != TM_ERROR_NONE) return status; - - if (lib->nondaemon_thread_count == 1 && !jvmti_thread->daemon) { - status = hymutex_unlock(&lib->TM_LOCK); - return status; - } - - while ((!jvmti_thread->daemon && lib->nondaemon_thread_count > 1) - || (jvmti_thread->daemon && lib->nondaemon_thread_count > 0)) { - status = hycond_wait(&lib->nondaemon_thread_cond, &lib->TM_LOCK); - //check interruption and other problems - TRACE(("TM wait for nondaemons notified, count: %d", lib->nondaemon_thread_count)); - if (status != TM_ERROR_NONE) { - hymutex_unlock(&lib->TM_LOCK); - return status; - } - } - - status = hymutex_unlock(&lib->TM_LOCK); - return status; -} +IDATA VMCALL jthread_wait_for_all_nondaemon_threads() +{ + hythread_t native_thread = hythread_self(); + jvmti_thread_t jvmti_thread = (jvmti_thread_t)hythread_get_private_data(native_thread); + return hythread_wait_for_nondaemon_threads(native_thread, + (jvmti_thread->daemon ? 0 : 1)); +} // jthread_wait_for_all_nondaemon_threads /* * Auxiliary function to throw java.lang.InterruptedException */ - -void throw_interrupted_exception(void) { - - jvmti_thread_t tm_java_thread; - hythread_t tm_native_thread; - jclass clazz; - JNIEnv *env; - +void throw_interrupted_exception(void) +{ TRACE(("interrupted_exception thrown")); - tm_native_thread = hythread_self(); - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - env = tm_java_thread->jenv; - clazz = env->FindClass("java/lang/InterruptedException"); + hythread_t native_thread = hythread_self(); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + JNIEnv *env = jvmti_thread->jenv; + jclass clazz = env->FindClass("java/lang/InterruptedException"); env->ThrowNew(clazz, "Park() is interrupted"); -} +} // throw_interrupted_exception -jmethodID getRunMethod(JNIEnv *env, jthread java_thread) { - jclass clazz; +static jmethodID jthread_get_run_method(JNIEnv * env, jthread java_thread) +{ static jmethodID run_method = NULL; - IDATA status; - - status=acquire_start_lock(); - assert(status == TM_ERROR_NONE); - //printf("run method find enter\n"); + + TRACE("run method find enter"); if (!run_method) { - clazz = env->GetObjectClass(java_thread); + jclass clazz = env->GetObjectClass(java_thread); run_method = env->GetMethodID(clazz, "runImpl", "()V"); } - status=release_start_lock(); - //printf("run method find exit\n"); - assert(status == TM_ERROR_NONE); + TRACE("run method find exit"); return run_method; -} - -IDATA increase_nondaemon_threads_count(hythread_t self) { - hythread_library_t lib; - IDATA status; - - lib = self->library; - - status = hymutex_lock(&lib->TM_LOCK); - if (status != TM_ERROR_NONE) return status; - - lib->nondaemon_thread_count++; - status = hymutex_unlock(&lib->TM_LOCK); - return status; -} - -IDATA countdown_nondaemon_threads(hythread_t self) { - hythread_library_t lib; - IDATA status; +} // jthread_get_run_method - lib = self->library; - - status = hymutex_lock(&lib->TM_LOCK); - if (status != TM_ERROR_NONE) return status; - - if (lib->nondaemon_thread_count <= 0) { - status = hymutex_unlock(&lib->TM_LOCK); - if (status != TM_ERROR_NONE) return status; - return TM_ERROR_ILLEGAL_STATE; - } - - TRACE(("TM: nondaemons decreased, thread: %p count: %d\n", self, lib->nondaemon_thread_count)); - lib->nondaemon_thread_count--; - if (lib->nondaemon_thread_count <= 1) { - status = hycond_notify_all(&lib->nondaemon_thread_cond); - TRACE(("TM: nondaemons all dead, thread: %p count: %d\n", self, lib->nondaemon_thread_count)); - if (status != TM_ERROR_NONE) { - hymutex_unlock(&lib->TM_LOCK); - return status; - } - } - - status = hymutex_unlock(&lib->TM_LOCK); - return status; -} diff --git a/vm/vmcore/src/thread/thread_java_interrupt.cpp b/vm/vmcore/src/thread/thread_java_interrupt.cpp index 65bb8a7..ce985da 100644 --- a/vm/vmcore/src/thread/thread_java_interrupt.cpp +++ b/vm/vmcore/src/thread/thread_java_interrupt.cpp @@ -22,7 +22,7 @@ #include #include -#include "thread_private.h" +#include "vm_threads.h" /** * Interrupt a thread. @@ -34,11 +34,12 @@ * @param[in] java_thread a thread to be interrupted * @sa java.lang.Thread.interrupt() */ -IDATA VMCALL jthread_interrupt(jthread java_thread) { - hythread_t tm_native_thread = jthread_get_native_thread(java_thread); +IDATA VMCALL jthread_interrupt(jthread java_thread) +{ + hythread_t tm_native_thread = jthread_get_native_thread(java_thread); hythread_interrupt(tm_native_thread); return TM_ERROR_NONE; -} +} // jthread_interrupt /** * Returns true if the thread thread is interrupted. @@ -50,11 +51,11 @@ IDATA VMCALL jthread_interrupt(jthread java_thread) { * is interrupted; false otherwise. * @sa java.lang.Thread.isInterrupted() */ -jboolean jthread_is_interrupted(jthread java_thread) { +jboolean jthread_is_interrupted(jthread java_thread) +{ hythread_t tm_native_thread = jthread_get_native_thread(java_thread); return hythread_interrupted(tm_native_thread) > 0; - -} +} // jthread_is_interrupted /** * Clears the interruption flag for the specific thread. @@ -62,7 +63,8 @@ jboolean jthread_is_interrupted(jthread java_thread) { * @param[in] java_thread where to clear interrupt flag * @sa java.lang.Thread.interrupted() */ -IDATA VMCALL jthread_clear_interrupted(jthread java_thread) { +IDATA VMCALL jthread_clear_interrupted(jthread java_thread) +{ hythread_t tm_native_thread = jthread_get_native_thread(java_thread); return hythread_clear_interrupted_other(tm_native_thread); -} +} // jthread_clear_interrupted diff --git a/vm/vmcore/src/thread/thread_java_iterator.cpp b/vm/vmcore/src/thread/thread_java_iterator.cpp index ffdeee0..95884ee 100644 --- a/vm/vmcore/src/thread/thread_java_iterator.cpp +++ b/vm/vmcore/src/thread/thread_java_iterator.cpp @@ -23,75 +23,75 @@ #include #include #include -#include "thread_private.h" - +#include "vm_threads.h" /** * Creates the iterator that can be used to walk over java threads. */ -jthread_iterator_t VMCALL jthread_iterator_create(void) { +jthread_iterator_t VMCALL jthread_iterator_create(void) +{ hythread_group_t java_thread_group = get_java_thread_group(); - return (jthread_iterator_t)hythread_iterator_create(java_thread_group); -} + return (jthread_iterator_t) + hythread_iterator_create(java_thread_group); +} // jthread_iterator_create /** * Releases the iterator. * * @param[in] it iterator */ -IDATA VMCALL jthread_iterator_release(jthread_iterator_t *it) { - return hythread_iterator_release((hythread_iterator_t *)it); -} +IDATA VMCALL jthread_iterator_release(jthread_iterator_t * it) +{ + return hythread_iterator_release((hythread_iterator_t *) it); +} // jthread_iterator_release /** * Resets the iterator such that it will start from the beginning. * * @param[in] it iterator */ -IDATA VMCALL jthread_iterator_reset(jthread_iterator_t *it) { - return hythread_iterator_reset((hythread_iterator_t *)it); -} +IDATA VMCALL jthread_iterator_reset(jthread_iterator_t * it) +{ + return hythread_iterator_reset((hythread_iterator_t *) it); +} // jthread_iterator_reset /** * Returns the next jthread using the given iterator. * * @param[in] it iterator */ -jthread VMCALL jthread_iterator_next(jthread_iterator_t *it) { - hythread_t tm_native_thread; - jvmti_thread_t tm_java_thread; - tm_native_thread = hythread_iterator_next((hythread_iterator_t *)it); - while (tm_native_thread!=NULL) - { - if (hythread_is_alive(tm_native_thread)) { - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - if (tm_java_thread) { - return (jthread)tm_java_thread->thread_object; +jthread VMCALL jthread_iterator_next(jthread_iterator_t * it) +{ + hythread_t native_thread = hythread_iterator_next((hythread_iterator_t *) it); + while (native_thread != NULL) { + if (hythread_is_alive(native_thread)) { + jvmti_thread_t jvmti_thread = (jvmti_thread_t) + hythread_get_private_data(native_thread); + if (jvmti_thread) { + return (jthread) jvmti_thread->thread_object; } } - tm_native_thread = hythread_iterator_next((hythread_iterator_t *)it); + native_thread = hythread_iterator_next((hythread_iterator_t *) it); } - return NULL; -} +} // jthread_iterator_next /** * Returns the the number of Java threads. * * @param[in] iterator */ -IDATA VMCALL jthread_iterator_size(jthread_iterator_t iterator) { - jthread res; - IDATA status; - int count=0; - status=jthread_iterator_reset(&iterator); +IDATA VMCALL jthread_iterator_size(jthread_iterator_t iterator) +{ + IDATA status = jthread_iterator_reset(&iterator); assert(status == TM_ERROR_NONE); - res = jthread_iterator_next(&iterator); - while (res!=NULL) { - count++; - res = jthread_iterator_next(&iterator); + jthread thread = jthread_iterator_next(&iterator); + int count = 0; + while (thread != NULL) { + count++; + thread = jthread_iterator_next(&iterator); } - status=jthread_iterator_reset(&iterator); + status = jthread_iterator_reset(&iterator); assert(status == TM_ERROR_NONE); return count; -} +} // jthread_iterator_size diff --git a/vm/vmcore/src/thread/thread_java_monitors.cpp b/vm/vmcore/src/thread/thread_java_monitors.cpp index e5d412e..fd85ef6 100644 --- a/vm/vmcore/src/thread/thread_java_monitors.cpp +++ b/vm/vmcore/src/thread/thread_java_monitors.cpp @@ -19,19 +19,20 @@ * @file thread_java_monitors.c * @brief Java thread monitors related functions */ - -#undef LOG_DOMAIN -#define LOG_DOMAIN "tm.monitor" +#include #include #include #include -#include "thread_private.h" +#include "vm_threads.h" #include "jni.h" -void add_owned_monitor(jobject monitor); -void remove_owned_monitor(jobject monitor); -void set_contended_monitor(jobject monitor); -void set_wait_monitor(jobject monitor); +#define LOG_DOMAIN "tm.monitor" +#include "cxxlog.h" + +static void jthread_add_owned_monitor(jobject monitor); +static void jthread_remove_owned_monitor(jobject monitor); +static void jthread_set_owned_monitor(jobject monitor); +static void jthread_set_wait_monitor(jobject monitor); /** @@ -43,18 +44,16 @@ void set_wait_monitor(jobject monitor); * * @param[in] monitor object where monitor needs to be initialized. */ -IDATA VMCALL jthread_monitor_init(jobject monitor) { - - hythread_thin_monitor_t *lockword; - IDATA status; +IDATA VMCALL jthread_monitor_init(jobject monitor) +{ assert(monitor); - + hythread_suspend_disable(); - lockword = vm_object_get_lockword_addr(monitor); - status = hythread_thin_monitor_create(lockword); + hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor); + IDATA status = hythread_thin_monitor_create(lockword); hythread_suspend_enable(); return status; -} +} // jthread_monitor_init @@ -66,27 +65,23 @@ IDATA VMCALL jthread_monitor_init(jobject monitor) { * @param[in] monitor object where monitor is located * @sa JNI::MonitorEnter() */ -IDATA VMCALL jthread_monitor_enter(jobject monitor) { - hythread_thin_monitor_t *lockword; - IDATA status; - // should be moved to event handler +IDATA VMCALL jthread_monitor_enter(jobject monitor) +{ + IDATA state; + hythread_t native_thread; apr_time_t enter_begin; - jvmti_thread_t tm_java_thread; - hythread_t tm_native_thread; - int disable_count; assert(monitor); hythread_suspend_disable(); - lockword = vm_object_get_lockword_addr(monitor); - status = hythread_thin_monitor_try_enter(lockword); + hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor); + IDATA status = hythread_thin_monitor_try_enter(lockword); if (status != TM_ERROR_EBUSY) { goto entered; } - ///////// #ifdef LOCK_RESERVATION // busy unreserve lock before blocking and inflating - while (TM_ERROR_NONE !=unreserve_lock(lockword)) { + while (TM_ERROR_NONE != hythread_unreserve_lock(lockword)) { hythread_yield(); hythread_safe_point(); hythread_exception_safe_point(); @@ -97,86 +92,98 @@ IDATA VMCALL jthread_monitor_enter(jobject monitor) { goto entered; } #endif //LOCK_RESERVATION - tm_native_thread = hythread_self(); - tm_native_thread->state &= ~TM_THREAD_STATE_RUNNABLE; - tm_native_thread->state |= TM_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER; + + native_thread = hythread_self(); + hythread_thread_lock(native_thread); + state = hythread_get_state(native_thread); + state &= ~TM_THREAD_STATE_RUNNABLE; + state |= TM_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER; + status = hythread_set_state(native_thread, state); + assert(status == TM_ERROR_NONE); + hythread_thread_unlock(native_thread); // should be moved to event handler if (ti_is_enabled()) { enter_begin = apr_time_now(); - disable_count = reset_suspend_disable(); - set_contended_monitor(monitor); + int disable_count = hythread_reset_suspend_disable(); + jthread_set_owned_monitor(monitor); jvmti_send_contended_enter_or_entered_monitor_event(monitor, 1); - set_suspend_disable(disable_count); - + hythread_set_suspend_disable(disable_count); } - + // busy wait and inflate // reload pointer after safepoints - lockword = vm_object_get_lockword_addr(monitor); - while ((status = hythread_thin_monitor_try_enter(lockword)) == TM_ERROR_EBUSY) { + 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)) { + + if (hythread_is_fat_lock(*lockword)) { status = hythread_thin_monitor_enter(lockword); - if (status != TM_ERROR_NONE) { - hythread_suspend_enable(); - assert(0); - return status; - } - goto contended_entered; + if (status != TM_ERROR_NONE) { + hythread_suspend_enable(); + assert(0); + return status; + } + goto contended_entered; } hythread_yield(); } assert(status == TM_ERROR_NONE); - if (!is_fat_lock(*lockword)) { - inflate_lock(lockword); + if (!hythread_is_fat_lock(*lockword)) { + hythread_inflate_lock(lockword); } + // do all ti staff here contended_entered: if (ti_is_enabled()) { - disable_count = reset_suspend_disable(); + int disable_count = hythread_reset_suspend_disable(); jvmti_send_contended_enter_or_entered_monitor_event(monitor, 0); - set_suspend_disable(disable_count); + hythread_set_suspend_disable(disable_count); // should be moved to event handler - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(hythread_self()); - tm_java_thread->blocked_time += apr_time_now()- enter_begin; - ///////// + jvmti_thread_t tm_java_thread = + (jvmti_thread_t) hythread_get_private_data(hythread_self()); + tm_java_thread->blocked_time += apr_time_now() - enter_begin; } - tm_native_thread->state &= ~TM_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER; - tm_native_thread->state |= TM_THREAD_STATE_RUNNABLE; + + hythread_thread_lock(native_thread); + state = hythread_get_state(native_thread); + state &= ~TM_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER; + state |= TM_THREAD_STATE_RUNNABLE; + status = hythread_set_state(native_thread, state); + assert(status == TM_ERROR_NONE); + hythread_thread_unlock(native_thread); entered: - if (ti_is_enabled()) { - add_owned_monitor(monitor); - } + if (ti_is_enabled()) { + jthread_add_owned_monitor(monitor); + } hythread_suspend_enable(); return TM_ERROR_NONE; -} +} // jthread_monitor_enter /** * Attempt to gain the ownership over monitor without blocking. * * @param[in] monitor object where monitor is located */ -IDATA VMCALL jthread_monitor_try_enter(jobject monitor) { - hythread_thin_monitor_t *lockword; - IDATA status; +IDATA VMCALL jthread_monitor_try_enter(jobject monitor) +{ assert(monitor); hythread_suspend_disable(); - lockword = vm_object_get_lockword_addr(monitor); - status = hythread_thin_monitor_try_enter(lockword); - + hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor); + IDATA status = hythread_thin_monitor_try_enter(lockword); hythread_suspend_enable(); + if (status == TM_ERROR_NONE && ti_is_enabled()) { - add_owned_monitor(monitor); + jthread_add_owned_monitor(monitor); } return status; -} +} // jthread_monitor_try_enter /** * Releases the ownership over monitor. @@ -184,24 +191,24 @@ IDATA VMCALL jthread_monitor_try_enter(jobject monitor) { * @param[in] monitor monitor * @sa JNI::MonitorExit() */ -IDATA VMCALL jthread_monitor_exit(jobject monitor) { - hythread_thin_monitor_t *lockword; - IDATA status; +IDATA VMCALL jthread_monitor_exit(jobject monitor) +{ assert(monitor); hythread_suspend_disable(); - - lockword = vm_object_get_lockword_addr(monitor); - status = hythread_thin_monitor_exit(lockword); + hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor); + IDATA status = hythread_thin_monitor_exit(lockword); hythread_suspend_enable(); + if (status == TM_ERROR_NONE && ti_is_enabled()) { - remove_owned_monitor(monitor); + jthread_remove_owned_monitor(monitor); } if (status == TM_ERROR_ILLEGAL_STATE) { - jthread_throw_exception("java/lang/IllegalMonitorStateException", "Illegal monitor state"); + jthread_throw_exception("java/lang/IllegalMonitorStateException", + "Illegal monitor state"); } return status; -} +} // jthread_monitor_exit /** * Notifies one thread waiting on the monitor. @@ -213,18 +220,17 @@ IDATA VMCALL jthread_monitor_exit(jobject monitor) { * @param[in] monitor object where monitor is located * @sa java.lang.Object.notify() */ -IDATA VMCALL jthread_monitor_notify(jobject monitor) { - hythread_thin_monitor_t *lockword; - IDATA status; +IDATA VMCALL jthread_monitor_notify(jobject monitor) +{ assert(monitor); hythread_suspend_disable(); - lockword = vm_object_get_lockword_addr(monitor); - status = hythread_thin_monitor_notify(lockword); + hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor); + IDATA status = hythread_thin_monitor_notify(lockword); hythread_suspend_enable(); return status; -} +} // jthread_monitor_notify /** * Notifies all threads which are waiting on the monitor. @@ -235,18 +241,17 @@ IDATA VMCALL jthread_monitor_notify(jobject monitor) { * @param[in] monitor object where monitor is located * @sa java.lang.Object.notifyAll() */ -IDATA VMCALL jthread_monitor_notify_all(jobject monitor) { - hythread_thin_monitor_t *lockword; - IDATA status; +IDATA VMCALL jthread_monitor_notify_all(jobject monitor) +{ assert(monitor); hythread_suspend_disable(); - lockword = vm_object_get_lockword_addr(monitor); - status = hythread_thin_monitor_notify_all(lockword); + hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor); + IDATA status = hythread_thin_monitor_notify_all(lockword); hythread_suspend_enable(); return status; -} +} // jthread_monitor_notify_all /** * Wait on the object's monitor. @@ -264,9 +269,10 @@ IDATA VMCALL jthread_monitor_notify_all(jobject monitor) { * @sa java.lang.Object.wait() * @return */ -IDATA VMCALL jthread_monitor_wait(jobject monitor) { +IDATA VMCALL jthread_monitor_wait(jobject monitor) +{ return jthread_monitor_timed_wait(monitor, 0, 0); -} +} // jthread_monitor_wait /** * Wait on the object's monitor with the specified timeout. @@ -287,89 +293,99 @@ IDATA VMCALL jthread_monitor_wait(jobject monitor) { * @param[in] nanos time to wait (in nanoseconds) * @sa java.lang.Object.wait() */ - -IDATA VMCALL jthread_monitor_timed_wait(jobject monitor, jlong millis, jint nanos) { - hythread_thin_monitor_t *lockword; - IDATA status; - hythread_t tm_native_thread; - apr_time_t wait_begin; - jvmti_thread_t tm_java_thread; - int disable_count; - +IDATA VMCALL +jthread_monitor_timed_wait(jobject monitor, jlong millis, jint nanos) +{ assert(monitor); hythread_suspend_disable(); - lockword = vm_object_get_lockword_addr(monitor); - if (!is_fat_lock(*lockword)) { - if (!owns_thin_lock(hythread_self(), *lockword)) { + hythread_t native_thread = hythread_self(); + hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor); + if (!hythread_is_fat_lock(*lockword)) { + if (!hythread_owns_thin_lock(native_thread, *lockword)) { TRACE(("ILLEGAL_STATE wait %x\n", lockword)); hythread_suspend_enable(); - return TM_ERROR_ILLEGAL_STATE; - } - inflate_lock(lockword); + return TM_ERROR_ILLEGAL_STATE; + } + hythread_inflate_lock(lockword); } + apr_time_t wait_begin; if (ti_is_enabled()) { - disable_count = reset_suspend_disable(); - set_wait_monitor(monitor); - set_contended_monitor(monitor); - jvmti_send_wait_monitor_event(monitor, (jlong)millis); + int disable_count = hythread_reset_suspend_disable(); + jthread_set_wait_monitor(monitor); + jthread_set_owned_monitor(monitor); + jvmti_send_wait_monitor_event(monitor, (jlong) millis); jvmti_send_contended_enter_or_entered_monitor_event(monitor, 1); - set_suspend_disable(disable_count); + hythread_set_suspend_disable(disable_count); // should be moved to event handler wait_begin = apr_time_now(); - //////// - remove_owned_monitor(monitor); + jthread_remove_owned_monitor(monitor); } - tm_native_thread = hythread_self(); - tm_native_thread->state &= ~TM_THREAD_STATE_RUNNABLE; - tm_native_thread->state |= TM_THREAD_STATE_WAITING | - TM_THREAD_STATE_IN_MONITOR_WAIT; - + hythread_thread_lock(native_thread); + 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) || (nanos > 0)) { - tm_native_thread->state |= TM_THREAD_STATE_WAITING_WITH_TIMEOUT; - } else { - tm_native_thread->state |= TM_THREAD_STATE_WAITING_INDEFINITELY; + state |= TM_THREAD_STATE_WAITING_WITH_TIMEOUT; + } + else { + state |= TM_THREAD_STATE_WAITING_INDEFINITELY; } + IDATA status = hythread_set_state(native_thread, state); + assert(status == TM_ERROR_NONE); + hythread_thread_unlock(native_thread); - status = hythread_thin_monitor_wait_interruptable(lockword, millis, nanos); + status = + hythread_thin_monitor_wait_interruptable(lockword, millis, nanos); - tm_native_thread->state &= ~(TM_THREAD_STATE_WAITING | - TM_THREAD_STATE_IN_MONITOR_WAIT); + hythread_thread_lock(native_thread); + state = hythread_get_state(native_thread); if ((millis > 0) || (nanos > 0)) { - tm_native_thread->state &= ~TM_THREAD_STATE_WAITING_WITH_TIMEOUT; - } else { - tm_native_thread->state &= ~TM_THREAD_STATE_WAITING_INDEFINITELY; + state &= ~TM_THREAD_STATE_WAITING_WITH_TIMEOUT; + } + else { + state &= ~TM_THREAD_STATE_WAITING_INDEFINITELY; } - tm_native_thread->state |= TM_THREAD_STATE_RUNNABLE; + state &= ~(TM_THREAD_STATE_WAITING | TM_THREAD_STATE_IN_MONITOR_WAIT); + state |= TM_THREAD_STATE_RUNNABLE; + hythread_set_state(native_thread, state); + hythread_thread_unlock(native_thread); hythread_suspend_enable(); if (ti_is_enabled()) { - add_owned_monitor(monitor); - disable_count = reset_suspend_disable(); + jthread_add_owned_monitor(monitor); + int disable_count = hythread_reset_suspend_disable(); jvmti_send_contended_enter_or_entered_monitor_event(monitor, 0); - jvmti_send_waited_monitor_event(monitor, (status == APR_TIMEUP)?(jboolean)1:(jboolean)0); + jvmti_send_waited_monitor_event(monitor, + ((status == APR_TIMEUP) ? (jboolean) 1 : (jboolean) 0)); + hythread_set_suspend_disable(disable_count); // should be moved to event handler - set_suspend_disable(disable_count); - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(hythread_self()); - tm_java_thread->waited_time += apr_time_now()- wait_begin; - ///////// + jvmti_thread_t tm_java_thread = + (jvmti_thread_t) hythread_get_private_data(hythread_self()); + tm_java_thread->waited_time += apr_time_now() - wait_begin; } return status; -} +} // jthread_monitor_timed_wait + +static void jthread_add_owned_monitor(jobject monitor) +{ + hythread_t native_thread = hythread_self(); + jvmti_thread_t tm_java_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); -void add_owned_monitor(jobject monitor){ - hythread_t tm_native_thread = hythread_self(); - jvmti_thread_t tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - int disable_status; TRACE(("TM: add owned monitor: %x", monitor)); - if (!tm_java_thread) return; - - disable_status = reset_suspend_disable(); + if (!tm_java_thread) { + return; + } + + int disable_status = hythread_reset_suspend_disable(); + if (tm_java_thread->contended_monitor) { - tm_java_thread->jenv->DeleteGlobalRef(tm_java_thread->contended_monitor); + tm_java_thread->jenv-> + DeleteGlobalRef(tm_java_thread->contended_monitor); tm_java_thread->contended_monitor = NULL; } @@ -377,69 +393,79 @@ void add_owned_monitor(jobject monitor){ tm_java_thread->jenv->DeleteGlobalRef(tm_java_thread->wait_monitor); tm_java_thread->wait_monitor = NULL; } - - + if (!tm_java_thread->owned_monitors) { - tm_java_thread->owned_monitors = (jobject*)apr_pcalloc(tm_java_thread->pool, - MAX_OWNED_MONITOR_NUMBER * sizeof(jobject)); - assert(tm_java_thread->owned_monitors); - tm_java_thread->owned_monitors_nmb = 0; + tm_java_thread->owned_monitors = + (jobject*) apr_pcalloc(tm_java_thread->pool, + TM_MAX_OWNED_MONITOR_NUMBER * sizeof(jobject)); + assert(tm_java_thread->owned_monitors); + tm_java_thread->owned_monitors_nmb = 0; } - assert(tm_java_thread->owned_monitors_nmb < MAX_OWNED_MONITOR_NUMBER); - - tm_java_thread->owned_monitors[tm_java_thread->owned_monitors_nmb] + assert(tm_java_thread->owned_monitors_nmb < TM_MAX_OWNED_MONITOR_NUMBER); + + tm_java_thread->owned_monitors[tm_java_thread->owned_monitors_nmb] = tm_java_thread->jenv->NewGlobalRef(monitor); - set_suspend_disable(disable_status); + hythread_set_suspend_disable(disable_status); + tm_java_thread->owned_monitors_nmb++; -} +} // jthread_add_owned_monitor + +static void jthread_remove_owned_monitor(jobject monitor) +{ + hythread_t native_thread = hythread_self(); + jvmti_thread_t tm_java_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); -void remove_owned_monitor(jobject monitor) { - int i,j, disable_status; - hythread_t tm_native_thread = hythread_self(); - jvmti_thread_t tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - TRACE(("TM: remove owned monitor: %x", monitor)); - - if (!tm_java_thread) return; - for (i = tm_java_thread->owned_monitors_nmb - 1; i >= 0; i--) { + + if (!tm_java_thread) { + return; + } + + for (int i = tm_java_thread->owned_monitors_nmb - 1; i >= 0; i--) { if (vm_objects_are_equal(tm_java_thread->owned_monitors[i], monitor)) { - disable_status = reset_suspend_disable(); - tm_java_thread->jenv->DeleteGlobalRef(tm_java_thread->owned_monitors[i]); - set_suspend_disable(disable_status); - for (j = i; j < tm_java_thread->owned_monitors_nmb - 1; j++) { - tm_java_thread->owned_monitors[j] = tm_java_thread->owned_monitors[j + 1]; + int disable_status = hythread_reset_suspend_disable(); + tm_java_thread->jenv->DeleteGlobalRef(tm_java_thread-> + owned_monitors[i]); + hythread_set_suspend_disable(disable_status); + for (int j = i; j < tm_java_thread->owned_monitors_nmb - 1; j++) { + tm_java_thread->owned_monitors[j] = + tm_java_thread->owned_monitors[j + 1]; } tm_java_thread->owned_monitors_nmb--; return; } } -} +} // jthread_remove_owned_monitor -void set_contended_monitor(jobject monitor){ - hythread_t tm_native_thread = hythread_self(); - IDATA suspend_status; - - jvmti_thread_t tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); +static void jthread_set_owned_monitor(jobject monitor) +{ + hythread_t native_thread = hythread_self(); + jvmti_thread_t tm_java_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); - if (!tm_java_thread) return; - - suspend_status = reset_suspend_disable(); - tm_java_thread->contended_monitor = tm_java_thread->jenv->NewGlobalRef(monitor); - - set_suspend_disable(suspend_status); -} + if (!tm_java_thread) { + return; + } -void set_wait_monitor(jobject monitor){ - hythread_t tm_native_thread = hythread_self(); - IDATA suspend_status; - - jvmti_thread_t tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); + int disable_count = hythread_reset_suspend_disable(); + tm_java_thread->contended_monitor = + tm_java_thread->jenv->NewGlobalRef(monitor); + hythread_set_suspend_disable(disable_count); +} // jthread_set_owned_monitor - if (!tm_java_thread) return; +static void jthread_set_wait_monitor(jobject monitor) +{ + hythread_t native_thread = hythread_self(); + jvmti_thread_t tm_java_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); - suspend_status = reset_suspend_disable(); - assert(suspend_status == TM_ERROR_NONE); - tm_java_thread->wait_monitor = tm_java_thread->jenv->NewGlobalRef(monitor); - set_suspend_disable(suspend_status); -} + if (!tm_java_thread) { + return; + } + int disable_count = hythread_reset_suspend_disable(); + tm_java_thread->wait_monitor = + tm_java_thread->jenv->NewGlobalRef(monitor); + hythread_set_suspend_disable(disable_count); +} // jthread_set_wait_monitor diff --git a/vm/vmcore/src/thread/thread_java_park.cpp b/vm/vmcore/src/thread/thread_java_park.cpp index 59865c7..f6c3db7 100644 --- a/vm/vmcore/src/thread/thread_java_park.cpp +++ b/vm/vmcore/src/thread/thread_java_park.cpp @@ -23,7 +23,7 @@ #include #include #include -#include "thread_private.h" +#include "vm_threads.h" /** * Parks the current thread. @@ -33,9 +33,10 @@ * * @sa java.util.concurrent.locks.LockSupport.park() */ -IDATA VMCALL jthread_park() { +IDATA VMCALL jthread_park() +{ return hythread_park(0, 0); -} +} // jthread_park /** * Parks the current thread with the specified timeout. @@ -48,9 +49,10 @@ IDATA VMCALL jthread_park() { * @param[in] nanos timeout in nanoseconds * @sa java.util.concurrent.locks.LockSupport.park() */ -IDATA VMCALL jthread_timed_park(jlong millis, jint nanos) { - return hythread_park((I_64)millis, (IDATA)nanos); -} +IDATA VMCALL jthread_timed_park(jlong millis, jint nanos) +{ + return hythread_park((I_64) millis, (IDATA) nanos); +} // jthread_timed_park /** * Unparks the given thread. @@ -65,15 +67,13 @@ IDATA VMCALL jthread_timed_park(jlong millis, jint nanos) { * @param[in] java_thread thread that needs to be unparked * @sa java.util.concurrent.locks.LockSupport.unpark() */ -IDATA VMCALL jthread_unpark(jthread java_thread) { - hythread_t tm_native_thread; - +IDATA VMCALL jthread_unpark(jthread java_thread) +{ assert(java_thread); - tm_native_thread = jthread_get_native_thread(java_thread); - hythread_unpark(tm_native_thread); - + hythread_t native_thread = jthread_get_native_thread(java_thread); + hythread_unpark(native_thread); return TM_ERROR_NONE; -} +} // jthread_unpark /** * Parks the current thread until the specified deadline @@ -85,8 +85,10 @@ IDATA VMCALL jthread_unpark(jthread java_thread) { * @param[in] millis absolute time in milliseconds to wait until * @sa java.util.concurrent.locks.LockSupport.parkUntil() */ -IDATA VMCALL jthread_park_until(jlong millis) { - jlong delta = millis - apr_time_now()/1000; - if (delta <= 0) return TM_ERROR_NONE; - return hythread_park((I_64)delta, 0); -} +IDATA VMCALL jthread_park_until(jlong millis) +{ + jlong delta = millis - apr_time_now() / 1000; + if (delta <= 0) + return TM_ERROR_NONE; + return hythread_park((I_64) delta, 0); +} // jthread_park_until diff --git a/vm/vmcore/src/thread/thread_java_suspend.cpp b/vm/vmcore/src/thread/thread_java_suspend.cpp index eadbab6..006ba43 100644 --- a/vm/vmcore/src/thread/thread_java_suspend.cpp +++ b/vm/vmcore/src/thread/thread_java_suspend.cpp @@ -22,7 +22,8 @@ #include #include -#include "thread_private.h" +#include +#include "vm_threads.h" /** * Resumes the suspended thread thread execution. @@ -34,11 +35,12 @@ * @param[in] java_thread thread to be resumed * @sa java.lang.Thread.resume(), JVMTI::ResumeThread() */ -IDATA VMCALL jthread_resume(jthread java_thread) { - hythread_t tm_native_thread = vm_jthread_get_tm_data(java_thread); - hythread_resume(tm_native_thread); +IDATA VMCALL jthread_resume(jthread java_thread) +{ + hythread_t native_thread = vm_jthread_get_tm_data(java_thread); + hythread_resume(native_thread); return TM_ERROR_NONE; -} +} // jthread_resume /** * Resumes the suspended threads from the list. @@ -48,14 +50,16 @@ IDATA VMCALL jthread_resume(jthread java_thread) { * @param[in] thread_list list of threads to be resumed * @sa JVMTI::ResumeThreadList() */ -IDATA VMCALL jthread_resume_all(jvmtiError* results, jint count, const jthread* thread_list) { - int i; - - for (i = 0; i < count; i++) { +IDATA VMCALL +jthread_resume_all(jvmtiError *results, + jint count, + const jthread *thread_list) +{ + for (jint i = 0; i < count; i++) { results[i] = (jvmtiError)jthread_resume(thread_list[i]); } return TM_ERROR_NONE; -} +} // jthread_resume_all /** * Suspends the thread execution. @@ -75,10 +79,11 @@ IDATA VMCALL jthread_resume_all(jvmtiError* results, jint count, const jthread* * @param[in] java_thread thread to be suspended * @sa java.lang.Thread.suspend(), JVMTI::SuspendThread() */ -IDATA VMCALL jthread_suspend(jthread java_thread) { - hythread_t tm_native_thread = vm_jthread_get_tm_data(java_thread); - return hythread_suspend_other(tm_native_thread); -} +IDATA VMCALL jthread_suspend(jthread java_thread) +{ + hythread_t native_thread = vm_jthread_get_tm_data(java_thread); + return hythread_suspend_other(native_thread); +} // jthread_suspend /** * Suspends the threads from the list. @@ -100,11 +105,13 @@ IDATA VMCALL jthread_suspend(jthread java_thread) { * @param[in] thread_list list of threads to be suspended * @sa JVMTI::SuspendThreadList() */ -IDATA VMCALL jthread_suspend_all(jvmtiError* results, jint count, const jthread* thread_list) { - int i; - for (i = 0; i < count; i++) { +IDATA VMCALL +jthread_suspend_all(jvmtiError *results, + jint count, + const jthread *thread_list) +{ + for (jint i = 0; i < count; i++) { results[i] = (jvmtiError)jthread_suspend(thread_list[i]); } return TM_ERROR_NONE; -} - +} // jthread_suspend_all diff --git a/vm/vmcore/src/thread/thread_manager.cpp b/vm/vmcore/src/thread/thread_manager.cpp index 2ea07cc..4e4a2f7 100644 --- a/vm/vmcore/src/thread/thread_manager.cpp +++ b/vm/vmcore/src/thread/thread_manager.cpp @@ -17,7 +17,7 @@ /** * @author Andrey Chernyshev * @version $Revision: 1.1.2.1.4.5 $ - */ + */ #include "open/thread_externals.h" @@ -76,10 +76,11 @@ using namespace std; hythread_tls_key_t TLS_key_pvmthread; #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -volatile VM_thread *p_the_safepoint_control_thread = 0; // only set when a gc is happening +volatile VM_thread *p_the_safepoint_control_thread = 0; // only set when a gc is happening volatile safepoint_state global_safepoint_status = nill; #ifdef __cplusplus @@ -89,72 +90,82 @@ volatile safepoint_state global_safepoint_status = nill; void init_TLS_data(); -VM_thread * allocate_thread_block(JavaVM_Internal * java_vm) { - VM_thread * p_vmthread; - apr_pool_t * thread_pool; - - if (apr_pool_create(&thread_pool, java_vm->vm_env->mem_pool) != APR_SUCCESS) { - return NULL; +VM_thread *allocate_thread_block(JavaVM_Internal * java_vm) +{ + VM_thread *p_vmthread; + apr_pool_t *thread_pool; + + if (apr_pool_create(&thread_pool, java_vm->vm_env->mem_pool) != + APR_SUCCESS) { + return NULL; } p_vmthread = (VM_thread *) apr_pcalloc(thread_pool, sizeof(VM_thread)); - if (!p_vmthread) return NULL; - + if (!p_vmthread) + return NULL; + p_vmthread->pool = thread_pool; return p_vmthread; } - -VM_thread * get_a_thread_block(JavaVM_Internal * java_vm) { - VM_thread * p_vmthread; + +VM_thread *get_a_thread_block(JavaVM_Internal * java_vm) +{ + VM_thread *p_vmthread; p_vmthread = p_TLS_vmthread; if (!p_vmthread) { - p_vmthread = allocate_thread_block(java_vm); - - if (!p_vmthread) return NULL; - set_TLS_data(p_vmthread); + p_vmthread = allocate_thread_block(java_vm); + + if (!p_vmthread) + return NULL; + set_TLS_data(p_vmthread); } else { memset(p_vmthread, 0, sizeof(VM_thread)); } return p_vmthread; -} +} -VM_thread *get_vm_thread_ptr_safe(JNIEnv *jenv, jobject jThreadObj) +VM_thread *get_vm_thread_ptr_safe(JNIEnv * jenv, jobject jThreadObj) { - hythread_t t=jthread_get_native_thread(jThreadObj); - if(t == NULL) { - return NULL; - } - return (VM_thread *)hythread_tls_get(t, TLS_key_pvmthread); + hythread_t t = jthread_get_native_thread(jThreadObj); + if (t == NULL) { + return NULL; + } + return (VM_thread *) hythread_tls_get(t, TLS_key_pvmthread); } VM_thread *get_thread_ptr_stub() -{ - return get_vm_thread(hythread_self()); +{ + return get_vm_thread(hythread_self()); } - -vm_thread_accessor* get_thread_ptr = get_thread_ptr_stub; -void init_TLS_data() { + +vm_thread_accessor *get_thread_ptr = get_thread_ptr_stub; + +void init_TLS_data() +{ //printf ("init TLS data, TLS key = %x \n", TLS_key_pvmthread); TLS_key_pvmthread = TM_THREAD_VM_TLS_KEY; } - -void set_TLS_data(VM_thread *thread) { + +void set_TLS_data(VM_thread * thread) +{ hythread_tls_set(hythread_self(), TLS_key_pvmthread, thread); //printf ("sett ls call %p %p\n", get_thread_ptr(), get_vm_thread(hythread_self())); } -IDATA jthread_throw_exception(char* name, char* message) { +IDATA jthread_throw_exception(char *name, char *message) +{ assert(hythread_is_suspend_enabled()); jobject jthe = exn_create(name); return jthread_throw_exception_object(jthe); } -IDATA jthread_throw_exception_object(jobject object) { +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. @@ -178,79 +189,96 @@ IDATA jthread_throw_exception_object(jobject object) { * This localizes the dependencies of Thread Manager on vmcore component. */ -hythread_thin_monitor_t * -vm_object_get_lockword_addr(jobject monitor) { +hythread_thin_monitor_t *vm_object_get_lockword_addr(jobject monitor) +{ assert(monitor); - return (hythread_thin_monitor_t*)(*(ManagedObject**)monitor)->get_obj_info_addr(); + return (hythread_thin_monitor_t *) (*(ManagedObject **) monitor)-> + get_obj_info_addr(); } -extern "C" char *vm_get_object_class_name(void* ptr) { - return (char*)(((ManagedObject*)ptr)->vt()->clss->get_name()->bytes); +extern "C" char *vm_get_object_class_name(void *ptr) +{ + return (char *) (((ManagedObject *) ptr)->vt()->clss->get_name()->bytes); } hythread_t vm_jthread_get_tm_data(jthread thread) { static int offset = -1; - Class * clazz; - Field * field; - ManagedObject * thread_obj; - Byte * java_ref; + Class *clazz; + Field *field; + ManagedObject *thread_obj; + Byte *java_ref; POINTER_SIZE_INT val; hythread_suspend_disable(); - thread_obj = ((ObjectHandle)thread)->object; + thread_obj = ((ObjectHandle) thread)->object; if (offset == -1) { clazz = thread_obj->vt()->clss; field = class_lookup_field_recursive(clazz, "vm_thread", "J"); offset = field->get_offset(); } - java_ref = (Byte *)thread_obj; - val = *(POINTER_SIZE_INT *)(java_ref + offset); + java_ref = (Byte *) thread_obj; + val = *(POINTER_SIZE_INT *) (java_ref + offset); hythread_suspend_enable(); - return (hythread_t)val; + return (hythread_t) val; } -void vm_jthread_set_tm_data(jthread thread, void* val) { +void vm_jthread_set_tm_data(jthread thread, void *val) +{ static int offset = -1; - Class * clazz; - Field * field; - ManagedObject * thread_obj; - Byte * java_ref; + Class *clazz; + Field *field; + ManagedObject *thread_obj; + Byte *java_ref; hythread_suspend_disable(); - thread_obj = ((ObjectHandle)thread)->object; + thread_obj = ((ObjectHandle) thread)->object; if (offset == -1) { clazz = thread_obj->vt()->clss; field = class_lookup_field_recursive(clazz, "vm_thread", "J"); offset = field->get_offset(); } - java_ref = (Byte *)thread_obj; - *(jlong *)(java_ref + offset) = (jlong)(POINTER_SIZE_INT)val; + java_ref = (Byte *) thread_obj; + *(jlong *) (java_ref + offset) = (jlong) (POINTER_SIZE_INT) val; hythread_suspend_enable(); } -int vm_objects_are_equal(jobject obj1, jobject obj2){ +int vm_objects_are_equal(jobject obj1, jobject obj2) +{ //ObjectHandle h1 = (ObjectHandle)obj1; //ObjectHandle h2 = (ObjectHandle)obj2; - if (obj1 == NULL && obj2 == NULL){ + if (obj1 == NULL && obj2 == NULL) { return 1; -} - if (obj1 == NULL || obj2 == NULL){ - return 0; -} - return obj1->object == obj2->object; } + if (obj1 == NULL || obj2 == NULL) { + return 0; + } + return obj1->object == obj2->object; +} -int ti_is_enabled(){ +int ti_is_enabled() +{ return VM_Global_State::loader_env->TI->isEnabled(); } -void set_ti_enabled(){ +void set_ti_enabled() +{ return VM_Global_State::loader_env->TI->setEnabled(); } + +/* + * Class: org_apache_harmony_drlvm_thread_ThreadHelper + * Method: getThreadIdOffset + * Signature: ()I + */ +jint JNICALL +Java_org_apache_harmony_drlvm_thread_ThreadHelper_getThreadIdOffset(JNIEnv *env, jclass klass) +{ + return hythread_get_thread_id_offset(); +} diff --git a/vm/vmcore/src/thread/thread_private.h b/vm/vmcore/src/thread/thread_private.h deleted file mode 100755 index 008a83b..0000000 --- a/vm/vmcore/src/thread/thread_private.h +++ /dev/null @@ -1,705 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef THREAD_PRIVATE_H -#define THREAD_PRIVATE_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "apr_thread_ext.h" - -#ifdef __linux__ -#include -#endif // __linux__ - -// temporary remove logging -//#define TRACE(a) //printf a; printf("\n") - -#ifdef __linux__ -#include "clog.h" -#else -#define TRACE(a) //printf a; printf("\n") -#define DIE(A) //exit(55); -#endif - -// FIXME move to the global header, add error converter -#define RET_ON_ERROR(stat) if (stat) { return -1; } -#define CONVERT_ERROR(stat) (stat) - -#define MAX_OWNED_MONITOR_NUMBER 200 //FIXME: switch to dynamic resize -#define FAST_LOCAL_STORAGE_SIZE 10 - -#define INITIAL_FAT_TABLE_ENTRIES 16*1024 //make this table exapandible if workloads show it is necessary - -#define HY_DEFAULT_STACKSIZE 512 * 1024 // if default stack size is not through -Xss parameter, it is 256kb - - -#if !defined (_IPF_) -//use lock reservation -#define LOCK_RESERVATION -// spin with try_lock SPIN_COUNT times -#define SPIN_COUNT 5 - -#endif // !defined (_IPF_) - -#if defined(_WIN32) && !defined (_EM64T_) -//use optimized asm monitor enter and exit helpers -#define ASM_MONITOR_HELPER -#endif - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -#ifdef __linux__ -#define osthread_t pthread_t -#elif _WIN32 -#define osthread_t HANDLE -#else // !_WIN32 && !__linux__ -#error "threading is only supported on __linux__ or _WIN32" -#endif // !_WIN32 && !__linux__ - - -extern hythread_group_t TM_DEFAULT_GROUP; -/** - * current capacity of the thread local storage - */ -extern int16 tm_tls_capacity; - -/** - * current capacity of the thread local storage - */ -extern int16 tm_tls_size; - - -typedef struct HyThreadLibrary { - IDATA a; - hymutex_t TM_LOCK; - IDATA nondaemon_thread_count; - hycond_t nondaemon_thread_cond; -} HyThreadLibrary; - -/** - * Native thread control structure. - */ -typedef struct HyThread { - -#ifndef POSIX - // This is dummy pointer for Microsoft Visual Studio debugging - // If this is removed, Visual Studio, when attached to VM, will show - // no symbolic information - void* reserved; -#endif - -// Public fields exported by HyThread_public. If you change these fields, -// please, check fields in hythread.h/HyThread_public - - /** - * 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; - - /** - * 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 disable_count; - - - /** - * Group for this thread. Different groups are needed in order - * to be able to quickly iterate over the specific group. - * Examples are: Java threads, GC private threads. - * Equal to the address of the head of the list of threads for this group. - */ - hythread_group_t group; - - /** - * Array representing thread local storage - */ - void *thread_local_storage[10]; - - -// Private fields - - /** - * Each thread keeps a pointer to the library it belongs to. - */ - HyThreadLibrary * library; - -// Suspension - - /** - * 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_count; - - - /** - * 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. - */ - hythread_event_callback_proc safepoint_callback; - - /** - * Event used to notify suspended thread that it needs to wake up. - */ - hysem_t resume_event; - -// Basic manipulation fields - - /** - * Points to the next thread within the group. - */ - hythread_t next; - - /** - * Points to the last thread within the group. - */ - hythread_t prev; - - /** - * Handle to OS thread. - */ - osthread_t os_handle; - - /** - * Placeholder for any data to be associated with this thread. - * Java layer is using it to keep java-specific context. - */ - void *private_data; - - /** - * Flag indicating there was request to exit - */ - Boolean exit_request; - - /** - * Exit value of this thread - */ - IDATA exit_value; - - -// Synchronization stuff - - /* - * Thread local lock, used to serialize thread state; - */ - hymutex_t mutex; - - /* - * Conditional variable used to implement wait function for sleep/park; - */ - hycond_t condition; - - /** - * Event reserved for threads that invoke join. - */ - hylatch_t join_event; - - /** - * Current conditional variable thread is waiting on (used for interrupting) - */ - hycond_t *current_condition; - -// State - - /** - * Thread state. Holds thread state flags as defined in JVMTI specification, plus some additional - * flags. See - * JVMTI Specification for more details. - */ - IDATA state; - - -// Attributes - - /** - * name of the thread (useful for debugging purposes) - */ - char* name; - - /** - * Hint for scheduler about thread priority - */ - IDATA priority; - - /** - * Size of thread's stack, set on creation - */ - - UDATA stacksize; - -// Monitors - - /** - * Monitor this thread is waiting on now. - **/ - hythread_monitor_t waited_monitor; - - /** - * ID for this thread. The maximum number of threads is governed by the size of lockword record. - */ - IDATA thread_id; - - /** - * APR thread attributes - */ - apr_threadattr_t *apr_attrs; - - /** - * Extension to the standard local storage slot. - */ - void **big_local_storage; - -} HyThread; - - -/** - * Java-specific context that is attached to tm_thread control structure by Java layer - */ -typedef struct JVMTIThread { - - /** - * JNI env associated with this Java thread - */ - JNIEnv *jenv; - - /** - * jthread object which is associated with tm_thread - */ - jthread thread_object; - - /** - * Conditional variable which is used to wait/notify on java monitors. - */ - hycond_t monitor_condition; - - /** - * Exception that has to be thrown in stopped thread - */ - jthrowable stop_exception; - - /** - * Blocked on monitor times count - */ - jlong blocked_count; - - /** - * Blocked on monitor time in nanoseconds - */ - jlong blocked_time; - - /** - * Waited on monitor times count - */ - jlong waited_count; - - /** - * Waited on monitor time in nanoseconds - */ - jlong waited_time; - - /** - * JVM TI local storage - */ - JVMTILocalStorage jvmti_local_storage; - - /** - * Monitor this thread is blocked on. - */ - jobject contended_monitor; - - /** - * Monitor this thread waits on. - */ - jobject wait_monitor; - - /** - * Monitors for which this thread is owner. - */ - jobject *owned_monitors; - - /** - * owned monitors count. - */ - int owned_monitors_nmb; - - /** - * APR pool for this structure - */ - apr_pool_t *pool; - - /** - * weak reference to corresponding java.lang.Thread instance - */ - jobject thread_ref; - - /** - * Is this thread daemon? - */ - IDATA daemon; - -} JVMTIThread; - - - -/** - * hythread_group_t pointer to the first element in the thread group - */ -typedef struct HyThreadGroup { - - /** - * Pointer to the first thread in the list of threads - * contained in this group - */ - hythread_t thread_list; - - - /** - * Pointer to the first thread in the list of threads - * contained in this group - */ - hythread_t thread_list_tail; - - /** - * Number of threads in this group - */ - int threads_count; - - /** - * Group index or key for search purposes - */ - int group_index; - - /** - * Memory pool to place created threads into. - */ - apr_pool_t* pool; - - /** - * - */ - hythread_group_t next; - - /** - * - */ - hythread_group_t prev; - -} HyThreadGroup; - - -/** - * Fat monitor structure. - * - * A simple combination of conditional variable and fat lock. - */ -typedef struct HyThreadMonitor { - - /** - * Mutex - */ - hymutex_t mutex; - - /** - * Condition variable - */ - hycond_t condition; - - /** - * Recursion count - */ - IDATA recursion_count; - hythread_t owner; - hythread_t inflate_owner; - hythread_t last_wait; - int inflate_count; - int wait_count; - int notify_flag; - - /** - * Owner thread ID. - */ - IDATA thread_id; - - UDATA flags; - - char *name; - -} HyThreadMonitor; - -/** - * Count down latch - */ -typedef struct HyLatch { - - /** - * Latch count - */ - int count; - - /** - * Condition event used to signal threads which are waiting on the latch. - */ - hycond_t condition; - - /** - * Mutex associated with the latch data. - */ - hymutex_t mutex; - /** - * latch sub pool - * will be destroyed by latch_destroy() - */ - apr_pool_t *pool; - -} HyLatch; - - -/** - * Semaphore - */ -typedef struct HySemaphore { - - /** - * Semaphore count - */ - int count; - - /** - * Semaphore max count - */ - int max_count; - - /** - * Condition event used to signal threads which are waiting on the semaphore. - */ - hycond_t condition; - - /** - * Mutex associated with the semaphore data. - */ - hymutex_t mutex; -} HySemaphore; - - -/* - * Lock table which holds the mapping between LockID and fat lock - * (OS fat_monitor) pointer. - */ - -typedef enum hythread_locktable_state { - HYTHREAD_LOCKTABLE_IDLE, - HYTHREAD_LOCKTABLE_READING, - HYTHREAD_LOCKTABLE_WRITING -} hythread_locktable_state_t; - -typedef struct HyFatLockTable { - // locktable itself - hythread_monitor_t *table; - - // mutex guarding locktable - hymutex_t mutex; - hycond_t read; - hycond_t write; - - int readers_reading; - int readers_waiting; - int writers_waiting; - - hythread_locktable_state_t state; - - U_32 read_count; - - // table of live objects (updated during each major GC) - unsigned char *live_objs; - - // size of locktable - U_32 size; - - // used to scan the lock table for the next available entry - U_32 array_cursor; - -} HyFatLockTable; - - -// Global variables - -extern hythread_group_t group_list; // list of thread groups -extern IDATA groups_count; // number of thread groups - -extern apr_pool_t *TM_POOL; //global APR pool for thread manager - -extern apr_threadkey_t *TM_THREAD_KEY; // Key used to store tm_thread_t structure in TLS - -extern int max_group_index; // max number of groups - -extern int total_started_thread_count; // Total started thread counter. - -extern HyFatLockTable *lock_table; - -#define THREAD_ID_SIZE 16 //size of thread ID in bits. Also defines max number of threads - - - -/** -* Internal TM functions -*/ - -/** -* tm_reset_suspend_disable() reset suspend_disable to 0, and return old value. -* It should be used with tm_set_suspend_disable() to implement safe points -* Will be used in tm_safe_point(), tm_mutex_lock(), tm_cond_wait(). -*/ - -int reset_suspend_disable(); -void set_suspend_disable(int count); - -/* thin monitor functions used java monitor - */ -IDATA is_fat_lock(hythread_thin_monitor_t lockword); -IDATA owns_thin_lock(hythread_t thread, I_32 lockword); -hythread_monitor_t inflate_lock(hythread_thin_monitor_t *lockword_ptr); -IDATA unreserve_lock(hythread_thin_monitor_t *lockword_ptr); - -IDATA VMCALL hythread_get_group(hythread_group_t *group, hythread_t thread); -/** - * Auxiliary function to throw java.lang.InterruptedException - */ - -void throw_interrupted_exception(void); - -hythread_group_t get_java_thread_group(void); - -/** - * Thread cancellation, being used at VM shutdown through - * tmj_cancel_all_threads() method call to terminate all java - * threads at shutdown. - */ - -typedef void (*tm_thread_event_callback_proc)(void); -IDATA VMCALL set_safepoint_callback(hythread_t thread, tm_thread_event_callback_proc callback); - -IDATA acquire_start_lock(void); -IDATA release_start_lock(void); - -IDATA thread_sleep_impl(I_64 millis, IDATA nanos, IDATA interruptable); -IDATA condvar_wait_impl(hycond_t *cond, hymutex_t *mutex, I_64 ms, IDATA nano, IDATA interruptable); -IDATA monitor_wait_impl(hythread_monitor_t mon_ptr, I_64 ms, IDATA nano, IDATA interruptable); -IDATA thin_monitor_wait_impl(hythread_thin_monitor_t *lockword_ptr, I_64 ms, IDATA nano, IDATA interruptable); -IDATA sem_wait_impl(hysem_t sem, I_64 ms, IDATA nano, IDATA interruptable); - -typedef struct ResizableArrayEntry { - void *entry; - UDATA next_free; -} ResizableArrayEntry; - -typedef struct ResizableArrayEntry *array_entry_t; - -typedef struct ResizableArrayType { - UDATA size; - UDATA capacity; - UDATA next_index; - array_entry_t entries; -} ResizableArrayType; -typedef struct ResizableArrayType *array_t; - - -IDATA array_create(array_t *array); -IDATA array_destroy(array_t array); -UDATA array_add(array_t array, void *value); -void *array_delete(array_t array, UDATA index); -void *array_get(array_t array, UDATA index); - -/** - * Auxiliary function to update thread count - */ -void thread_start_count(); -void thread_end_count(); - -/* - * portability functions, private for thread module - */ -int os_thread_create(osthread_t* phandle, UDATA stacksize, UDATA priority, - int (VMAPICALL *func)(void*), void *data); -int os_thread_set_priority(osthread_t thread, int priority); -osthread_t os_thread_current(); -int os_thread_cancel(osthread_t); -int os_thread_join(osthread_t); -void os_thread_exit(int status); -void os_thread_yield_other(osthread_t); -int os_get_thread_times(osthread_t os_thread, int64* pkernel, int64* puser); - -int os_cond_timedwait(hycond_t *cond, hymutex_t *mutex, I_64 ms, IDATA nano); -UDATA os_get_foreign_thread_stack_size(); - -#ifdef __cplusplus -} -#endif - -#endif /* THREAD_PRIVATE_H */ diff --git a/vm/vmcore/src/thread/thread_ti_instr.cpp b/vm/vmcore/src/thread/thread_ti_instr.cpp index ca06431..11f6a67 100644 --- a/vm/vmcore/src/thread/thread_ti_instr.cpp +++ b/vm/vmcore/src/thread/thread_ti_instr.cpp @@ -18,12 +18,13 @@ /** * @file thread_ti_instr.c * @brief JVMTI basic related functions - */ + */ #include #include #include -#include "thread_private.h" +#include +#include "vm_threads.h" /** * Returns the list of all Java threads. @@ -31,84 +32,62 @@ * @param[out] threads resulting threads list * @param[out] count_ptr number of threads in the resulting list */ -IDATA VMCALL jthread_get_all_threads(jthread** threads, jint *count_ptr) { - - hythread_group_t java_thread_group = get_java_thread_group(); - hythread_iterator_t iterator; - hythread_t tm_native_thread; - jvmti_thread_t tm_java_thread; - jthread* java_threads; - int i; - int count = 0; - int java_thread_count = 0; - IDATA status; - //apr_status_t apr_status; - //apr_pool_t *pool; +IDATA VMCALL jthread_get_all_threads(jthread ** threads, jint * count_ptr) +{ + assert(threads); + assert(count_ptr); + hythread_group_t java_thread_group = get_java_thread_group(); assert(java_thread_group); - iterator = hythread_iterator_create(java_thread_group); - count = hythread_iterator_size (iterator); - for (i = 0; i < count; i++) { - tm_native_thread = hythread_iterator_next(&iterator); - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - if (tm_java_thread) { + hythread_iterator_t iterator = hythread_iterator_create(java_thread_group); + IDATA count = hythread_iterator_size(iterator); + + IDATA java_thread_count = 0; + for (IDATA i = 0; i < count; i++) { + hythread_t native_thread = hythread_iterator_next(&iterator); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + if (jvmti_thread) { java_thread_count++; } } - /*apr_status = apr_pool_create(&pool, 0); - if (apr_status != APR_SUCCESS) { - hythread_iterator_release(&iterator); - return CONVERT_ERROR(apr_status); - } - java_threads = apr_palloc(pool, sizeof(jthread)* java_thread_count);*/ - java_threads = (jthread*)malloc(sizeof(jthread)* java_thread_count); + + jthread *java_threads = (jthread*)malloc(sizeof(jthread) * java_thread_count); if (!java_threads) { hythread_iterator_release(&iterator); return TM_ERROR_OUT_OF_MEMORY; } + hythread_iterator_reset(&iterator); java_thread_count = 0; - for (i = 0; i < count; i++) { - tm_native_thread = hythread_iterator_next(&iterator); - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - if (tm_java_thread) { - java_threads[java_thread_count] = tm_java_thread->thread_object; - java_thread_count++; + for (IDATA i = 0; i < count; i++) { + hythread_t native_thread = hythread_iterator_next(&iterator); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + if (jvmti_thread) { + java_threads[java_thread_count++] = jvmti_thread->thread_object; } } *threads = java_threads; - *count_ptr = java_thread_count; - status = hythread_iterator_release(&iterator); + *count_ptr = (jint)java_thread_count; + IDATA status = hythread_iterator_release(&iterator); return status; -} -/* - */ -IDATA deads_expand(jthread **deads, int deads_size) { +} // jthread_get_all_threads - jthread *new_deads; - int i; - new_deads = (jthread *)malloc(sizeof(jthread) * deads_size * 2); - if (!new_deads) return TM_ERROR_OUT_OF_MEMORY; - - for (i = 0; i < deads_size; i++) { - new_deads[i] = (*deads)[i]; - } - *deads = new_deads; - return TM_ERROR_NONE; -} /* */ -int deads_find(jobject thread, jobject *deads, int base, int top, int deads_size) { - int i; - - for (i = 0; i < top; i++) { +int +jthread_find_deads(jobject thread, jobject *deads, int base, int top) +{ + for (int i = 0; i < top; i++) { if (vm_objects_are_equal(thread, deads[i])) { return 1; } } return 0; } + // FIXME: synchronization and maybe thread suspension needed /** * Checks for the deadlock conditions within the specified thread list. @@ -118,176 +97,173 @@ int deads_find(jobject thread, jobject *deads, int base, int top, int deads_size * @param[out] dead_list deadlocked threads * @param[out] dead_count number of deadlocked threads */ -IDATA VMCALL jthread_get_deadlocked_threads(jthread *thread_list, jint thread_count, jthread **dead_list, jint *dead_count) { - jthread *deads; - int deads_size = 1; - int deads_base = 0; - int deads_top = 0; - jthread *output; - int output_top = 0; - jobject monitor; - jthread thread; - //apr_pool_t *pool; - /*apr_pool_t *pool_out; - apr_status_t apr_status;*/ - IDATA status; - int i; - - /*apr_status = apr_pool_create(&pool, NULL); - if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status); - - deads = apr_palloc(pool, sizeof(jthread) * deads_size); - output = apr_palloc(pool, sizeof(jthread) * thread_count); - if (!deads || !output) return TM_ERROR_OUT_OF_MEMORY;*/ - - deads = (jthread *)malloc(sizeof(jthread) * deads_size); - output = (jthread *)malloc(sizeof(jthread) * thread_count); - if ((deads==NULL)||(output==NULL)) { - return TM_ERROR_OUT_OF_MEMORY; +IDATA VMCALL +jthread_get_deadlocked_threads(jthread * thread_list, + jint thread_count, + jthread ** dead_list, + jint * dead_count) +{ + int deads_size; + int deads_base; + int deads_top; + int output_top; + + IDATA status = TM_ERROR_NONE; + jthread *deads = (jthread *) malloc(sizeof(jthread) * thread_count); + jthread *output = (jthread *) malloc(sizeof(jthread) * thread_count); + if ((deads == NULL) || (output == NULL)) { + status = TM_ERROR_OUT_OF_MEMORY; + goto free_allocated_memory; } - for (i = 0; i < thread_count; i++) { - thread = thread_list[i]; - while (1) { - status=jthread_get_contended_monitor(thread, &monitor); - if (status != TM_ERROR_NONE) return status; - if (! monitor) { + + deads_size = 1; + deads_base = 0; + deads_top = 0; + output_top = 0; + for (jint i = 0; i < thread_count; i++) { + jthread thread = thread_list[i]; + output[output_top] = thread; + while (true) { + jobject monitor; + IDATA status = jthread_get_contended_monitor(thread, &monitor); + if (status != TM_ERROR_NONE) { + goto free_allocated_memory; + } + if (!monitor) { deads_top = deads_base; // remove frame break; } - if (deads_find(thread, deads, deads_base, deads_top, deads_size)) { - output[output_top] = thread; + if (jthread_find_deads(thread, deads, deads_base, deads_top)) { output_top++; deads_base = deads_top; // add frame break; } if (deads_top == deads_size) { - status = deads_expand(&deads, deads_size); - if (status != TM_ERROR_NONE) return status; + // status = deads_expand(&deads, deads_size); + if (status != TM_ERROR_NONE) + return status; } deads[deads_top] = thread; deads_top++; status = jthread_get_lock_owner(monitor, &thread); - if (status != TM_ERROR_NONE) return status; + if (status != TM_ERROR_NONE) { + goto free_allocated_memory; + } } } if (output_top > 0) { - /* apr_status = apr_pool_create(&pool_out, NULL); - if (apr_status != APR_SUCCESS) return CONVERT_ERROR(apr_status);*/ - *dead_list = (jthread *)malloc(sizeof(jthread) * output_top); - if (! *dead_list) return TM_ERROR_OUT_OF_MEMORY; - - for (i = 0; i < output_top; i++) { - (*dead_list)[i] = output[i]; + output = (jthread*)realloc(output, sizeof(jthread) * output_top); + if (!output) { + status = TM_ERROR_OUT_OF_MEMORY; + goto free_allocated_memory; } + *dead_list = output; } else { *dead_list = NULL; } *dead_count = output_top; + if (!deads) { + free(deads); + } return TM_ERROR_NONE; -} + +free_allocated_memory: + if (!deads) { + free(deads); + } + if (!output) { + free(output); + } + return status; +} // jthread_get_deadlocked_threads /** * Returns the number of all Java threads. * * @param[out] count_ptr number of threads. */ -IDATA VMCALL jthread_get_thread_count(jint *count_ptr) { - - hythread_group_t java_thread_group = get_java_thread_group(); - hythread_iterator_t iterator; - hythread_t tm_native_thread; - jvmti_thread_t tm_java_thread; - int i; - int count = 0; - int java_thread_count = 0; - IDATA status; - +IDATA VMCALL jthread_get_thread_count(jint * count_ptr) +{ + assert(count_ptr); + hythread_group_t java_thread_group = get_java_thread_group(); assert(java_thread_group); - iterator = hythread_iterator_create(java_thread_group); - count = hythread_iterator_size (iterator); - for (i = 0; i < count; i++) { - tm_native_thread = hythread_iterator_next(&iterator); - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - if (tm_java_thread) { + hythread_iterator_t iterator = hythread_iterator_create(java_thread_group); + IDATA count = hythread_iterator_size(iterator); + + IDATA java_thread_count = 0; + for (IDATA i = 0; i < count; i++) { + hythread_t native_thread = hythread_iterator_next(&iterator); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + if (jvmti_thread) { java_thread_count++; } } *count_ptr = java_thread_count; - status = hythread_iterator_release(&iterator); + IDATA status = hythread_iterator_release(&iterator); return status; -} - -/** - * Returns the number of total started Java threads. - * - * @param[out] count_ptr number of started threads. - */ -IDATA VMCALL jthread_get_total_started_thread_count(jint *count_ptr) { - *count_ptr = total_started_thread_count; - return TM_ERROR_NONE; -} +} // jthread_get_thread_count /** * Returns the number of blocked threads. * * @param[out] count_ptr number of threads. */ -IDATA VMCALL jthread_get_blocked_count(jint* count_ptr) { - - hythread_group_t java_thread_group = get_java_thread_group(); - hythread_iterator_t iterator; - hythread_t tm_native_thread; - int nmb = 0; - int count; - IDATA status; +IDATA VMCALL jthread_get_blocked_count(jint * count_ptr) +{ + assert(count_ptr); + hythread_group_t java_thread_group = get_java_thread_group(); assert(java_thread_group); - iterator = hythread_iterator_create(java_thread_group); - count = hythread_iterator_size (iterator); - - while (hythread_iterator_has_next(iterator)) { - tm_native_thread = hythread_iterator_next(&iterator); - if (tm_native_thread && hythread_is_blocked_on_monitor_enter(tm_native_thread)) { - nmb++; + hythread_iterator_t iterator = hythread_iterator_create(java_thread_group); + IDATA count = hythread_iterator_size(iterator); + + IDATA thread_count = 0; + for (IDATA i = 0; i < count; i++) { + hythread_t native_thread = hythread_iterator_next(&iterator); + if (native_thread + && hythread_is_blocked_on_monitor_enter(native_thread)) + { + thread_count++; } } - *count_ptr = nmb; - status = hythread_iterator_release(&iterator); + *count_ptr = thread_count; + IDATA status = hythread_iterator_release(&iterator); - return status; -} + return status; +} // jthread_get_blocked_count /** * Returns the number of waiting threads. * * @param[out] count number of threads. */ -IDATA VMCALL jthread_get_waited_count(jint* count) { - - hythread_group_t java_thread_group = get_java_thread_group(); - hythread_iterator_t iterator; - hythread_t tm_native_thread; - int nmb = 0; - IDATA status; +IDATA VMCALL jthread_get_waited_count(jint * count_ptr) +{ + assert(count_ptr); + hythread_group_t java_thread_group = get_java_thread_group(); assert(java_thread_group); - iterator = hythread_iterator_create(java_thread_group); - - while (hythread_iterator_has_next(iterator)) { - tm_native_thread = hythread_iterator_next(&iterator); - //if (hythread_is_in_monitor_wait(tm_native_thread)) { ??????????????????????? - if (hythread_is_waiting(tm_native_thread)) { - nmb++; + hythread_iterator_t iterator = hythread_iterator_create(java_thread_group); + IDATA count = hythread_iterator_size(iterator); + + IDATA thread_count = 0; + for (IDATA i = 0; i < count; i++) { + hythread_t native_thread = hythread_iterator_next(&iterator); + if (native_thread + && hythread_is_waiting(native_thread)) + { + thread_count++; } } - *count = nmb; - status = hythread_iterator_release(&iterator); + *count_ptr = thread_count; + IDATA status = hythread_iterator_release(&iterator); return status; -} +} // jthread_get_waited_count /** * Returns the thread's state according @@ -298,48 +274,73 @@ IDATA VMCALL jthread_get_waited_count(jint* count) { * @param[out] state resulting thread state * */ -IDATA VMCALL jthread_get_state(jthread java_thread, jint *state) { - hythread_t tm_native_thread; - - assert(java_thread); +IDATA VMCALL jthread_get_jvmti_state(jthread java_thread, jint * state) +{ assert(state); - tm_native_thread = vm_jthread_get_tm_data(java_thread); + assert(java_thread); *state = 0; - if (! tm_native_thread) return TM_ERROR_NONE; // Not started yet - - if (hythread_is_alive(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_ALIVE;} - if (hythread_is_runnable(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_RUNNABLE;} - if (hythread_is_blocked_on_monitor_enter(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;} - if (hythread_is_waiting(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_WAITING;} - if (hythread_is_waiting_indefinitely(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY;} - if (hythread_is_waiting_with_timeout(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;} - if (hythread_is_sleeping(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_SLEEPING;} - if (hythread_is_in_monitor_wait(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;} - if (hythread_is_parked(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_PARKED;} - if (hythread_is_suspended(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_SUSPENDED;} - if (hythread_interrupted(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_INTERRUPTED;} - if (hythread_is_in_native(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_IN_NATIVE;} - if (hythread_is_terminated(tm_native_thread)) {*state |= JVMTI_THREAD_STATE_TERMINATED;} + hythread_t native_thread = vm_jthread_get_tm_data(java_thread); + if (!native_thread) { + // Not started yet + return TM_ERROR_NONE; + } + if (hythread_is_alive(native_thread)) { + *state |= JVMTI_THREAD_STATE_ALIVE; + } + if (hythread_is_runnable(native_thread)) { + *state |= JVMTI_THREAD_STATE_RUNNABLE; + } + if (hythread_is_blocked_on_monitor_enter(native_thread)) { + *state |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER; + } + if (hythread_is_waiting(native_thread)) { + *state |= JVMTI_THREAD_STATE_WAITING; + } + if (hythread_is_waiting_indefinitely(native_thread)) { + *state |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY; + } + if (hythread_is_waiting_with_timeout(native_thread)) { + *state |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT; + } + if (hythread_is_sleeping(native_thread)) { + *state |= JVMTI_THREAD_STATE_SLEEPING; + } + if (hythread_is_in_monitor_wait(native_thread)) { + *state |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT; + } + if (hythread_is_parked(native_thread)) { + *state |= JVMTI_THREAD_STATE_PARKED; + } + if (hythread_is_suspended(native_thread)) { + *state |= JVMTI_THREAD_STATE_SUSPENDED; + } + if (hythread_interrupted(native_thread)) { + *state |= JVMTI_THREAD_STATE_INTERRUPTED; + } + if (hythread_is_in_native(native_thread)) { + *state |= JVMTI_THREAD_STATE_IN_NATIVE; + } + if (hythread_is_terminated(native_thread)) { + *state |= JVMTI_THREAD_STATE_TERMINATED; + } return TM_ERROR_NONE; -} - +} // jthread_get_jvmti_state + /** * Puts the data into thread local storage. * * @param[in] java_thread thread where to put the data * @param[in] data data to be put */ -IDATA VMCALL jthread_set_local_storage(jthread java_thread, const void* data) { - hythread_t tm_native_thread; - +IDATA VMCALL jthread_set_local_storage(jthread java_thread, const void *data) +{ assert(java_thread); - tm_native_thread = vm_jthread_get_tm_data(java_thread); - assert(tm_native_thread); - - return hythread_set_private_data(tm_native_thread, (void *)data); -} + hythread_t native_thread = vm_jthread_get_tm_data(java_thread); + assert(native_thread); + return hythread_set_private_data(native_thread, (void *)data); +} // jthread_set_local_storage /** * Extracts the data from the thread local storage. @@ -347,17 +348,16 @@ IDATA VMCALL jthread_set_local_storage(jthread java_thread, const void* data) { * @param[in] java_thread thread where to get the data * @param[out] data_ptr pointer to the data */ -IDATA VMCALL jthread_get_local_storage(jthread java_thread, void** data_ptr) { - hythread_t tm_native_thread; - - assert(java_thread); +IDATA VMCALL jthread_get_local_storage(jthread java_thread, void **data_ptr) +{ assert(data_ptr); - tm_native_thread = vm_jthread_get_tm_data(java_thread); - assert(tm_native_thread); - *data_ptr = (jvmti_thread_t)hythread_get_private_data (tm_native_thread); + assert(java_thread); + hythread_t native_thread = vm_jthread_get_tm_data(java_thread); + assert(native_thread); + *data_ptr = hythread_get_private_data(native_thread); return TM_ERROR_NONE; -} +} // jthread_get_local_storage /** * Returns true if specified thread holds the lock associated with the given monitor. @@ -366,21 +366,18 @@ IDATA VMCALL jthread_get_local_storage(jthread java_thread, void** data_ptr) { * @param[in] monitor object those monitor is possibly locked * @return true if thread holds the lock, false otherwise; */ -jboolean VMCALL jthread_holds_lock(jthread thread, jobject monitor) { +jboolean VMCALL jthread_holds_lock(jthread thread, jobject monitor) +{ + jthread lock_owner; + IDATA status = jthread_get_lock_owner(monitor, &lock_owner); + assert(status == TM_ERROR_NONE); - jthread lock_owner; - IDATA status; - jboolean res; - - status = jthread_get_lock_owner(monitor, &lock_owner); - assert(status == TM_ERROR_NONE); - - hythread_suspend_disable(); - res = vm_objects_are_equal(thread, lock_owner); - hythread_suspend_enable(); + hythread_suspend_disable(); + jboolean result = vm_objects_are_equal(thread, lock_owner); + hythread_suspend_enable(); - return res; -} + return result; +} // jthread_holds_lock /** * Returns the monitor the specific thread is currently contending for. @@ -389,18 +386,17 @@ jboolean VMCALL jthread_holds_lock(jthread thread, jobject monitor) { * @param[out] monitor monitor the thread thread is currently contending for, * or NULL if thread doesn't contend for any monitor. */ -IDATA VMCALL jthread_get_contended_monitor(jthread java_thread, jobject* monitor) { - - hythread_t tm_native_thread; - jvmti_thread_t tm_java_thread; - +IDATA VMCALL +jthread_get_contended_monitor(jthread java_thread, jobject * monitor) +{ assert(java_thread); - tm_native_thread = vm_jthread_get_tm_data(java_thread); - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - assert(tm_java_thread); - *monitor = tm_java_thread->contended_monitor; + hythread_t native_thread = vm_jthread_get_tm_data(java_thread); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + assert(jvmti_thread); + *monitor = jvmti_thread->contended_monitor; return TM_ERROR_NONE; -} +} // jthread_get_contended_monitor /** * Returns the monitor the specific thread is currently waiting on. @@ -409,18 +405,16 @@ IDATA VMCALL jthread_get_contended_monitor(jthread java_thread, jobject* monitor * @param[out] monitor monitor the thread thread is currently contending for, * or NULL if thread doesn't contend for any monitor. */ -IDATA VMCALL jthread_get_wait_monitor(jthread java_thread, jobject* monitor) { - - hythread_t tm_native_thread; - jvmti_thread_t tm_java_thread; - +IDATA VMCALL jthread_get_wait_monitor(jthread java_thread, jobject * monitor) +{ assert(java_thread); - tm_native_thread = vm_jthread_get_tm_data(java_thread); - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - assert(tm_java_thread); - *monitor = tm_java_thread->wait_monitor; + hythread_t native_thread = vm_jthread_get_tm_data(java_thread); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + assert(jvmti_thread); + *monitor = jvmti_thread->wait_monitor; return TM_ERROR_NONE; -} +} // jthread_get_wait_monitor /** * Returns the owner of the lock associated with the given monitor. @@ -430,26 +424,25 @@ IDATA VMCALL jthread_get_wait_monitor(jthread java_thread, jobject* monitor) { * @param[in] monitor monitor those owner needs to be determined * @param[out] lock_owner thread which owns the monitor */ -IDATA VMCALL jthread_get_lock_owner(jobject monitor, jthread* lock_owner) { - - hythread_t tm_native_thread = NULL; - jvmti_thread_t tm_java_thread = NULL; - hythread_thin_monitor_t *lockword; - +IDATA VMCALL jthread_get_lock_owner(jobject monitor, jthread * lock_owner) +{ assert(monitor); + assert(lock_owner); + hythread_suspend_disable(); - lockword = vm_object_get_lockword_addr(monitor); - tm_native_thread = hythread_thin_monitor_get_owner(lockword); - if (!tm_native_thread) { + hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor); + hythread_t native_thread = hythread_thin_monitor_get_owner(lockword); + if (!native_thread) { *lock_owner = NULL; } else { - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - *lock_owner = tm_java_thread->thread_object; + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + *lock_owner = jvmti_thread->thread_object; } hythread_suspend_enable(); return TM_ERROR_NONE; -} +} // jthread_get_lock_owner /** * Returns the number of times given thread have entered given monitor; @@ -459,27 +452,27 @@ IDATA VMCALL jthread_get_lock_owner(jobject monitor, jthread* lock_owner) { * @param[in] monitor monitor those owner needs to be determined * @param[in] owner thread which owns the monitor */ -IDATA VMCALL jthread_get_lock_recursion(jobject monitor, jthread owner) { +IDATA VMCALL jthread_get_lock_recursion(jobject monitor, jthread owner) +{ + assert(monitor); - hythread_t given_thread, lock_owner = NULL; - jvmti_thread_t tm_java_thread = NULL; - hythread_thin_monitor_t *lockword; - IDATA recursion = 0; + hythread_t given_thread = owner ? vm_jthread_get_tm_data(owner) : NULL; - assert(monitor); - given_thread = owner?vm_jthread_get_tm_data(owner):NULL; hythread_suspend_disable(); - - lockword = vm_object_get_lockword_addr(monitor); - lock_owner = hythread_thin_monitor_get_owner(lockword); - - if (lock_owner && (!given_thread || lock_owner->thread_id == given_thread->thread_id)) + hythread_thin_monitor_t *lockword = vm_object_get_lockword_addr(monitor); + hythread_t lock_owner = hythread_thin_monitor_get_owner(lockword); + + IDATA recursion = 0; + if (lock_owner + && (!given_thread + || hythread_get_id(lock_owner) == hythread_get_id(given_thread))) + { recursion = hythread_thin_monitor_get_recursion(lockword); - + } hythread_suspend_enable(); return recursion; -} +} // jthread_get_lock_recursion /** * Returns all monitors owned by the specific thread. @@ -488,40 +481,37 @@ IDATA VMCALL jthread_get_lock_recursion(jobject monitor, jthread owner) { * @param[out] monitor_count_ptr number of owned monitors * @param[out] monitors_ptr array of owned monitors */ -IDATA VMCALL jthread_get_owned_monitors(jthread java_thread, - jint* monitor_count_ptr, jobject** monitors_ptr) { - - hythread_t tm_native_thread; - jvmti_thread_t tm_java_thread; - // apr_pool_t* pool; - // apr_status_t apr_status; - jobject* monitors; - int i; - IDATA status; - - status =hythread_global_lock(); - if (status != TM_ERROR_NONE) return status; +IDATA VMCALL +jthread_get_owned_monitors(jthread java_thread, + jint *monitor_count_ptr, + jobject **monitors_ptr) +{ assert(java_thread); - tm_native_thread = vm_jthread_get_tm_data(java_thread); - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - assert(tm_java_thread); - /* apr_status = apr_pool_create(&pool, 0); - if (apr_status != APR_SUCCESS) { - hythread_global_unlock(); - return TM_ERROR_INTERNAL; + assert(monitors_ptr); + assert(monitor_count_ptr); + + IDATA status = hythread_global_lock(); + if (status != TM_ERROR_NONE) { + return status; } - monitors = apr_palloc(pool, sizeof(jobject*) * tm_java_thread->owned_monitors_nmb); */ - monitors = (jobject *)malloc(sizeof(jobject*) * tm_java_thread->owned_monitors_nmb); + hythread_t native_thread = vm_jthread_get_tm_data(java_thread); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + assert(jvmti_thread); + + jobject *monitors = + (jobject *) malloc(sizeof(jobject *) * + jvmti_thread->owned_monitors_nmb); if (!monitors) { hythread_global_unlock(); return TM_ERROR_OUT_OF_MEMORY; } - for (i = 0; i < tm_java_thread->owned_monitors_nmb; i++) { - monitors[i] = tm_java_thread->owned_monitors[i]; + for (int i = 0; i < jvmti_thread->owned_monitors_nmb; i++) { + monitors[i] = jvmti_thread->owned_monitors[i]; } *monitors_ptr = monitors; - *monitor_count_ptr = tm_java_thread->owned_monitors_nmb; + *monitor_count_ptr = jvmti_thread->owned_monitors_nmb; status = hythread_global_unlock(); return status; -} +} // jthread_get_owned_monitors diff --git a/vm/vmcore/src/thread/thread_ti_monitors.cpp b/vm/vmcore/src/thread/thread_ti_monitors.cpp index e7c550e..5447107 100644 --- a/vm/vmcore/src/thread/thread_ti_monitors.cpp +++ b/vm/vmcore/src/thread/thread_ti_monitors.cpp @@ -18,15 +18,131 @@ /** * @file thread_ti_monitors.c * @brief JVMTI raw monitors related functions - */ + */ #include -#include "thread_private.h" +#include "vm_threads.h" + +typedef struct ResizableArrayEntry *array_entry_t; +typedef struct ResizableArrayType *array_t; + +struct ResizableArrayEntry { + void *entry; + UDATA next_free; +}; + +struct ResizableArrayType { + UDATA size; + UDATA capacity; + UDATA next_index; + array_entry_t entries; +}; + +/** + * Resizable array implementation + */ +static IDATA array_create(array_t * arr) +{ + array_t ptr = (array_t) malloc(sizeof(ResizableArrayType)); + if (!ptr) { + return -1; + } + ptr->capacity = 1024; + ptr->size = 0; + ptr->next_index = 0; + ptr->entries = + (array_entry_t) malloc(sizeof(ResizableArrayEntry) * ptr->capacity); + if (!ptr->entries) { + free(ptr); + return -1; + } + *arr = ptr; + return 0; +} // array_create + +static IDATA array_destroy(array_t arr) +{ + if (!arr) { + return -1; + } + free(arr->entries); + free(arr); + return 0; +} // array_destroy + +static UDATA array_add(array_t arr, void *value) +{ + UDATA index; + if (!arr) { + return 0; + } + if (arr->next_index) { + index = arr->next_index; + } else { + index = arr->size + 1; + if (index >= arr->capacity) { + arr->entries = (array_entry_t)realloc(arr->entries, + sizeof(void *) * arr->capacity * 2); + if (!arr->entries) + return 0; + arr->capacity *= 2; + } + arr->entries[index].next_free = 0; + } + arr->next_index = arr->entries[index].next_free; + arr->entries[index].entry = value; + arr->size++; + + return index; +} // array_add + +static void * array_delete(array_t arr, UDATA index) +{ + void *return_value; + if (!arr || index > arr->size || index == 0) { + return NULL; + } + return_value = arr->entries[index].entry; + + arr->entries[index].entry = NULL; + arr->entries[index].next_free = arr->next_index; + arr->next_index = index; + + return return_value; +} // array_delete + +static void * array_get(array_t arr, UDATA index) +{ + if (!arr || index > arr->size || index == 0) { + return NULL; + } + return arr->entries[index].entry; +} // array_get static array_t jvmti_monitor_table = 0; static hymutex_t jvmti_monitor_table_lock; -//#define jrawMonitorID hythread_monitor_t; +static IDATA jthread_init_jvmti_monitor_table() +{ + IDATA status = hythread_global_lock(); + if (status != TM_ERROR_NONE) { + return status; + } + if (!jvmti_monitor_table) { + if (array_create(&jvmti_monitor_table)) { + hythread_global_unlock(); + return TM_ERROR_OUT_OF_MEMORY; + } + status = hymutex_create(&jvmti_monitor_table_lock, TM_MUTEX_NESTED); + if (status != TM_ERROR_NONE) { + hythread_global_unlock(); + return status; + } + } + status = hythread_global_unlock(); + return status; +} // jthread_init_jvmti_monitor_table + /** * Initializes raw monitor. * @@ -37,68 +153,67 @@ static hymutex_t jvmti_monitor_table_lock; * * @param[in] mon_ptr address where monitor needs to be created and initialized. */ -IDATA VMCALL jthread_raw_monitor_create(jrawMonitorID* mon_ptr) { +IDATA VMCALL jthread_raw_monitor_create(jrawMonitorID * mon_ptr) +{ + assert(mon_ptr); + hythread_monitor_t monitor; - IDATA status; - status = hythread_monitor_init(&monitor, 0); - if (status != TM_ERROR_NONE) return status; + IDATA status = hythread_monitor_init(&monitor, 0); + if (status != TM_ERROR_NONE) { + return status; + } + // possibly should be moved to jvmti(environment?) init section - //// if (!jvmti_monitor_table) { - status =hythread_global_lock(); - if (status != TM_ERROR_NONE) return status; - if (!jvmti_monitor_table) { - - if (array_create(&jvmti_monitor_table)) { - hythread_global_unlock(); - return TM_ERROR_OUT_OF_MEMORY; - } - status = hymutex_create(&jvmti_monitor_table_lock, TM_MUTEX_NESTED); - if (status != TM_ERROR_NONE) { - hythread_global_unlock(); - return status; - } + status = jthread_init_jvmti_monitor_table(); + if (status != TM_ERROR_NONE) { + return status; } - status =hythread_global_unlock(); - if (status != TM_ERROR_NONE) return status; } - - status =hymutex_lock(&jvmti_monitor_table_lock); - if (status != TM_ERROR_NONE) return status; - *mon_ptr = array_add(jvmti_monitor_table, monitor); - status =hymutex_unlock(&jvmti_monitor_table_lock); - if (status != TM_ERROR_NONE) return status; - if (!(*mon_ptr)) return TM_ERROR_OUT_OF_MEMORY; + status = hymutex_lock(&jvmti_monitor_table_lock); + if (status != TM_ERROR_NONE) { + return status; + } + *mon_ptr = array_add(jvmti_monitor_table, monitor); + if (!(*mon_ptr)) { + hymutex_unlock(&jvmti_monitor_table_lock); + return TM_ERROR_OUT_OF_MEMORY; + } - return TM_ERROR_NONE; - -} + status = hymutex_unlock(&jvmti_monitor_table_lock); + return status; +} // jthread_raw_monitor_create /** * Destroys raw monitor. * * @param[in] mon_ptr address where monitor needs to be destroyed. */ -IDATA VMCALL jthread_raw_monitor_destroy(jrawMonitorID mon_ptr) { - IDATA status = 0; - hythread_monitor_t monitor; - - if (!(monitor = (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr))) { +IDATA VMCALL jthread_raw_monitor_destroy(jrawMonitorID mon_ptr) +{ + hythread_monitor_t monitor = + (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr); + if (!monitor) { return TM_ERROR_INVALID_MONITOR; } - while (hythread_monitor_destroy((hythread_monitor_t)monitor) != TM_ERROR_NONE) { - if ((status = hythread_monitor_exit((hythread_monitor_t)monitor)) != TM_ERROR_NONE) + while (hythread_monitor_destroy((hythread_monitor_t)monitor) != TM_ERROR_NONE) + { + IDATA status = hythread_monitor_exit((hythread_monitor_t) monitor); + if (status != TM_ERROR_NONE) { return status; + } + } + + IDATA status = hymutex_lock(&jvmti_monitor_table_lock); + if (status != TM_ERROR_NONE) { + return status; } - - status =hymutex_lock(&jvmti_monitor_table_lock); - if (status != TM_ERROR_NONE) return status; - array_delete(jvmti_monitor_table, (UDATA)mon_ptr); - status =hymutex_unlock(&jvmti_monitor_table_lock); + array_delete(jvmti_monitor_table, (UDATA) mon_ptr); + status = hymutex_unlock(&jvmti_monitor_table_lock); return status; -} +} // jthread_raw_monitor_destroy /** * Gains the ownership over monitor. @@ -107,17 +222,18 @@ IDATA VMCALL jthread_raw_monitor_destroy(jrawMonitorID mon_ptr) { * * @param[in] mon_ptr monitor */ -IDATA VMCALL jthread_raw_monitor_enter(jrawMonitorID mon_ptr) { - hythread_monitor_t monitor; - IDATA stat; - if (!(monitor = (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr))) { +IDATA VMCALL jthread_raw_monitor_enter(jrawMonitorID mon_ptr) +{ + hythread_monitor_t monitor = + (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr); + if (!monitor) { return TM_ERROR_INVALID_MONITOR; } - stat = hythread_monitor_enter(monitor); + IDATA status = hythread_monitor_enter(monitor); hythread_safe_point(); hythread_exception_safe_point(); - return stat; -} + return status; +} // jthread_raw_monitor_enter /** * Attempt to gain the ownership over monitor without blocking. @@ -125,30 +241,33 @@ IDATA VMCALL jthread_raw_monitor_enter(jrawMonitorID mon_ptr) { * @param[in] mon_ptr monitor * @return 0 in case of successful attempt. */ -IDATA VMCALL jthread_raw_monitor_try_enter(jrawMonitorID mon_ptr) { - hythread_monitor_t monitor; - if (!(monitor = (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr))) { +IDATA VMCALL jthread_raw_monitor_try_enter(jrawMonitorID mon_ptr) +{ + hythread_monitor_t monitor = + (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr); + if (!monitor) { return TM_ERROR_INVALID_MONITOR; } - return hythread_monitor_try_enter((hythread_monitor_t)monitor); -} + return hythread_monitor_try_enter((hythread_monitor_t) monitor); +} // jthread_raw_monitor_try_enter /** * Releases the ownership over monitor. * * @param[in] mon_ptr monitor */ -IDATA VMCALL jthread_raw_monitor_exit(jrawMonitorID mon_ptr) { - hythread_monitor_t monitor; - IDATA stat; - if (!(monitor = (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr))) { +IDATA VMCALL jthread_raw_monitor_exit(jrawMonitorID mon_ptr) +{ + hythread_monitor_t monitor = + (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr); + if (!monitor) { return TM_ERROR_INVALID_MONITOR; } - stat = hythread_monitor_exit(monitor); + IDATA status = hythread_monitor_exit(monitor); hythread_safe_point(); hythread_exception_safe_point(); - return stat; -} + return status; +} // jthread_raw_monitor_exit /** * Wait on the monitor. @@ -171,15 +290,15 @@ IDATA VMCALL jthread_raw_monitor_exit(jrawMonitorID mon_ptr) { * TM_ERROR_INTERRUPT wait was interrupted * TM_ERROR_INVALID_MONITOR current thread isn't the owner */ -IDATA VMCALL jthread_raw_monitor_wait(jrawMonitorID mon_ptr, I_64 millis) { - hythread_monitor_t monitor; - - if (!(monitor = (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr))) { +IDATA VMCALL jthread_raw_monitor_wait(jrawMonitorID mon_ptr, I_64 millis) +{ + hythread_monitor_t monitor = + (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr); + if (!monitor) { return TM_ERROR_INVALID_MONITOR; } - return hythread_monitor_wait_interruptable(monitor, millis, 0); -} +} // jthread_raw_monitor_wait /** * Notifies one thread waiting on the monitor. @@ -190,13 +309,15 @@ IDATA VMCALL jthread_raw_monitor_wait(jrawMonitorID mon_ptr, I_64 millis) { * * @param[in] mon_ptr monitor */ -IDATA VMCALL jthread_raw_monitor_notify(jrawMonitorID mon_ptr) { - hythread_monitor_t monitor; - if (!(monitor = (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr))) { +IDATA VMCALL jthread_raw_monitor_notify(jrawMonitorID mon_ptr) +{ + hythread_monitor_t monitor = + (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr); + if (!monitor) { return TM_ERROR_INVALID_MONITOR; } - return hythread_monitor_notify(monitor); -} + return hythread_monitor_notify(monitor); +} // jthread_raw_monitor_notify /** * Notifies all threads which are waiting on the monitor. @@ -206,10 +327,12 @@ IDATA VMCALL jthread_raw_monitor_notify(jrawMonitorID mon_ptr) { * * @param[in] mon_ptr monitor */ -IDATA VMCALL jthread_raw_monitor_notify_all(jrawMonitorID mon_ptr) { - hythread_monitor_t monitor; - if (!(monitor = (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr))) { +IDATA VMCALL jthread_raw_monitor_notify_all(jrawMonitorID mon_ptr) +{ + hythread_monitor_t monitor = + (hythread_monitor_t)array_get(jvmti_monitor_table, (UDATA)mon_ptr); + if (!monitor) { return TM_ERROR_INVALID_MONITOR; } - return hythread_monitor_notify_all(monitor); -} + return hythread_monitor_notify_all(monitor); +} // jthread_raw_monitor_notify_all diff --git a/vm/vmcore/src/thread/thread_ti_others.cpp b/vm/vmcore/src/thread/thread_ti_others.cpp index ff6f072..46ed26e 100644 --- a/vm/vmcore/src/thread/thread_ti_others.cpp +++ b/vm/vmcore/src/thread/thread_ti_others.cpp @@ -18,114 +18,130 @@ /** * @file thread_ti_others.c * @brief JVMTI peak related functions - */ + */ #include #include #include -#include "thread_private.h" +#include +#include "vm_threads.h" #define THREAD_CONTENTION_MONITORING_SUPPORTED 1 /* * Monitors contentions requests enabled flag. */ -int thread_contention_monitoring_enabled = 0; +static int thread_contention_monitoring_enabled = 0; /* * Total started thread counter. */ -int total_started_thread_count = 0; +static int total_started_thread_count = 0; /* * Alive thread counter. */ -int alive_thread_count = 0; +static int alive_thread_count = 0; /* * Peak count */ -int peak_thread_count = 0; - +static int peak_thread_count = 0; + /** * Resets the thread peak counter to current value. */ -IDATA jthread_reset_peak_thread_count () { - +IDATA jthread_reset_peak_thread_count() +{ peak_thread_count = alive_thread_count; return TM_ERROR_NONE; -} +} // jthread_reset_peak_thread_count /** * Returns the peak thread count since the last peak reset. */ -IDATA jthread_get_peak_thread_count (jint *threads_count_ptr) { +IDATA jthread_get_peak_thread_count(jint * threads_count_ptr) +{ *threads_count_ptr = peak_thread_count; return TM_ERROR_NONE; -} - +} // jthread_get_peak_thread_count + /** * Returns true if VM supports monitors contention requests and * this feature is enabled * * @return true if monitors contention requests are enabled, false otherwise; */ -jboolean jthread_is_thread_contention_monitoring_enabled(){ +jboolean jthread_is_thread_contention_monitoring_enabled() +{ return thread_contention_monitoring_enabled; -} +} // jthread_is_thread_contention_monitoring_enabled /** * Returns true if VM supports monitors contention requests * * @return true if monitors contention requests are supported, false otherwise; */ -jboolean jthread_is_thread_contention_monitoring_supported(){ - +jboolean jthread_is_thread_contention_monitoring_supported() +{ return THREAD_CONTENTION_MONITORING_SUPPORTED; -} +} // jthread_is_thread_contention_monitoring_supported /** * Enabled or diabled thread monitors contention requests * * @param[in] true or false to enable or disable the feature */ -void jthread_set_thread_contention_monitoring_enabled(jboolean flag){ - - thread_contention_monitoring_enabled = THREAD_CONTENTION_MONITORING_SUPPORTED ? flag : 0; -} +void jthread_set_thread_contention_monitoring_enabled(jboolean flag) +{ + thread_contention_monitoring_enabled = + THREAD_CONTENTION_MONITORING_SUPPORTED ? flag : 0; +} // jthread_set_thread_contention_monitoring_enabled /** * Returns JVMTILocalStorage pointer. * * @param[in] java_thread */ -JVMTILocalStorage* jthread_get_jvmti_local_storage(jthread java_thread) { - - jvmti_thread_t tm_java_thread; - hythread_t tm_native_thread; +JVMTILocalStorage *jthread_get_jvmti_local_storage(jthread java_thread) +{ + assert(java_thread); + hythread_t native_thread = vm_jthread_get_tm_data(java_thread); + assert(native_thread); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + assert(jvmti_thread); + return &jvmti_thread->jvmti_local_storage; +} // jthread_get_jvmti_local_storage - tm_native_thread = vm_jthread_get_tm_data(java_thread); - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - - return &tm_java_thread->jvmti_local_storage; - -} +/** + * Returns the number of total started Java threads. + * + * @param[out] count_ptr number of started threads. + */ +IDATA VMCALL jthread_get_total_started_thread_count(jint * count_ptr) +{ + assert(count_ptr); + *count_ptr = total_started_thread_count; + return TM_ERROR_NONE; +} // jthread_get_total_started_thread_count /** * Increase thread counters. */ -void thread_start_count(){ +void jthread_start_count() +{ alive_thread_count++; total_started_thread_count++; if (peak_thread_count < alive_thread_count) { peak_thread_count = alive_thread_count; } -} +} // jthread_start_count /** * Decrease alive thread counter. */ -void thread_end_count(){ +void jthread_end_count() +{ alive_thread_count--; -} - +} // jthread_end_count diff --git a/vm/vmcore/src/thread/thread_ti_timing.cpp b/vm/vmcore/src/thread/thread_ti_timing.cpp index 5969466..55b0382 100644 --- a/vm/vmcore/src/thread/thread_ti_timing.cpp +++ b/vm/vmcore/src/thread/thread_ti_timing.cpp @@ -23,7 +23,8 @@ #include #include #include -#include "thread_private.h" +#include +#include "vm_threads.h" #include "apr_thread_ext.h" #define THREAD_CPU_TIME_SUPPORTED 1 @@ -39,19 +40,20 @@ int thread_cpu_time_enabled = 0; * @param[in] java_thread * @param[out] nanos_ptr CPU time in nanoseconds */ -IDATA VMCALL jthread_get_thread_blocked_time(jthread java_thread, jlong *nanos_ptr) { - - jvmti_thread_t tm_java_thread; - hythread_t tm_native_thread; - +IDATA VMCALL +jthread_get_thread_blocked_time(jthread java_thread, jlong * nanos_ptr) +{ assert(java_thread); assert(nanos_ptr); - tm_native_thread = vm_jthread_get_tm_data(java_thread); - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - *nanos_ptr = tm_java_thread->blocked_time; + hythread_t native_thread = vm_jthread_get_tm_data(java_thread); + assert(native_thread); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + assert(jvmti_thread); + *nanos_ptr = jvmti_thread->blocked_time; return TM_ERROR_NONE; -} +} // jthread_get_thread_blocked_time /** * Returns time utilized by given thread. @@ -59,29 +61,28 @@ IDATA VMCALL jthread_get_thread_blocked_time(jthread java_thread, jlong *nanos_p * @param[in] java_thread * @param[out] nanos_ptr CPU time in nanoseconds */ -IDATA VMCALL jthread_get_thread_cpu_time(jthread java_thread, jlong *nanos_ptr) { - - hythread_t tm_native_thread; +IDATA VMCALL +jthread_get_thread_cpu_time(jthread java_thread, jlong * nanos_ptr) +{ int64 kernel_time; - assert(nanos_ptr); - - if (NULL == java_thread) { - tm_native_thread = hythread_self(); - } else { - tm_native_thread = vm_jthread_get_tm_data(java_thread); - } - return hythread_get_thread_times(tm_native_thread, &kernel_time, nanos_ptr); -} + assert(nanos_ptr); + hythread_t native_thread = java_thread + ? hythread_self() : vm_jthread_get_tm_data(java_thread); + assert(native_thread); + return hythread_get_thread_times(native_thread, &kernel_time, + nanos_ptr); +} // jthread_get_thread_cpu_time /** * Returns information about the system timer. * * @param[out] info_ptr timer info */ -IDATA VMCALL jthread_get_thread_cpu_timer_info(jvmtiTimerInfo* info_ptr) { +IDATA VMCALL jthread_get_thread_cpu_timer_info(jvmtiTimerInfo * info_ptr) +{ return TM_ERROR_NONE; -} +} // jthread_get_thread_cpu_timer_info /** * Returns time utilized by the given thread in user mode. @@ -89,20 +90,22 @@ IDATA VMCALL jthread_get_thread_cpu_timer_info(jvmtiTimerInfo* info_ptr) { * @param[in] java_thread * @param[out] nanos_ptr CPU time in nanoseconds */ -IDATA VMCALL jthread_get_thread_user_cpu_time(jthread java_thread, jlong *nanos_ptr) { +IDATA VMCALL +jthread_get_thread_user_cpu_time(jthread java_thread, jlong * nanos_ptr) +{ + assert(nanos_ptr); + assert(java_thread); + hythread_t native_thread = vm_jthread_get_tm_data(java_thread); + assert(native_thread); - hythread_t tm_native_thread; int64 kernel_time; int64 user_time; - - assert(java_thread); - assert(nanos_ptr); - tm_native_thread = vm_jthread_get_tm_data(java_thread); - hythread_get_thread_times(tm_native_thread, &kernel_time, &user_time); + IDATA status = hythread_get_thread_times(native_thread, + &kernel_time, &user_time); + assert(status != TM_ERROR_NONE); *nanos_ptr = user_time; - return TM_ERROR_NONE; -} +} // jthread_get_thread_user_cpu_time /** * Returns time spent by the specific thread while waiting for monitors. @@ -110,19 +113,21 @@ IDATA VMCALL jthread_get_thread_user_cpu_time(jthread java_thread, jlong *nanos_ * @param[in] java_thread * @param[out] nanos_ptr CPU time in nanoseconds */ -IDATA VMCALL jthread_get_thread_waited_time(jthread java_thread, jlong *nanos_ptr) { - - jvmti_thread_t tm_java_thread; - hythread_t tm_native_thread; - +IDATA VMCALL +jthread_get_thread_waited_time(jthread java_thread, jlong * nanos_ptr) +{ assert(java_thread); assert(nanos_ptr); - tm_native_thread = vm_jthread_get_tm_data(java_thread); - tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); - *nanos_ptr = tm_java_thread->waited_time; + hythread_t native_thread = vm_jthread_get_tm_data(java_thread); + assert(native_thread); + + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + assert(jvmti_thread); + *nanos_ptr = jvmti_thread->waited_time; return TM_ERROR_NONE; -} +} // jthread_get_thread_waited_time /** * Returns number of times the specific thread contending for monitors. @@ -130,13 +135,17 @@ IDATA VMCALL jthread_get_thread_waited_time(jthread java_thread, jlong *nanos_pt * @param[in] java_thread * @return number of times the specific thread contending for monitors */ -jlong VMCALL jthread_get_thread_blocked_times_count(jthread java_thread) { - - hythread_t tm_native_thread = jthread_get_native_thread(java_thread); - jvmti_thread_t tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); +jlong VMCALL jthread_get_thread_blocked_times_count(jthread java_thread) +{ + assert(java_thread); + hythread_t native_thread = jthread_get_native_thread(java_thread); + assert(native_thread); - return tm_java_thread->blocked_count; -} + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); + assert(jvmti_thread); + return jvmti_thread->blocked_count; +} // jthread_get_thread_blocked_times_count /** * Returns number of times the specific thread waiting on monitors for notification. @@ -144,31 +153,35 @@ jlong VMCALL jthread_get_thread_blocked_times_count(jthread java_thread) { * @param[in] java_thread * @return number of times the specific thread waiting on monitors for notification */ -jlong VMCALL jthread_get_thread_waited_times_count(jthread java_thread) { - - hythread_t tm_native_thread = jthread_get_native_thread(java_thread); - jvmti_thread_t tm_java_thread = (jvmti_thread_t)hythread_get_private_data(tm_native_thread); +jlong VMCALL jthread_get_thread_waited_times_count(jthread java_thread) +{ + + hythread_t native_thread = jthread_get_native_thread(java_thread); + jvmti_thread_t jvmti_thread = + (jvmti_thread_t) hythread_get_private_data(native_thread); - return tm_java_thread->waited_count; -} + return jvmti_thread->waited_count; +} // jthread_get_thread_waited_times_count /** * Returns true if VM supports current thread CPU and USER time requests * * @return true if current thread CPU and USER time requests are supported, false otherwise; */ -jboolean jthread_is_current_thread_cpu_time_supported(){ +jboolean jthread_is_current_thread_cpu_time_supported() +{ return THREAD_CPU_TIME_SUPPORTED; -} +} // jthread_is_current_thread_cpu_time_supported /** * Returns true if VM supports thread CPU and USER time requests * * @return true if thread CPU and USER time requests are supported, false otherwise; */ -jboolean jthread_is_thread_cpu_time_supported(){ +jboolean jthread_is_thread_cpu_time_supported() +{ return THREAD_CPU_TIME_SUPPORTED; -} +} // jthread_is_thread_cpu_time_supported /** * Returns true if VM supports (current) thread CPU and USER time requests and @@ -176,15 +189,17 @@ jboolean jthread_is_thread_cpu_time_supported(){ * * @return true if thread CPU and USER time requests are enabled, false otherwise; */ -jboolean jthread_is_thread_cpu_time_enabled(){ +jboolean jthread_is_thread_cpu_time_enabled() +{ return thread_cpu_time_enabled; -} +} // jthread_is_thread_cpu_time_enabled /** * Enabled or diabled thread CPU and USER time requests * * @param[in] true or false to enable or disable the feature */ -void jthread_set_thread_cpu_time_enabled(jboolean flag){ - thread_cpu_time_enabled = THREAD_CPU_TIME_SUPPORTED ? flag : 0; -} +void jthread_set_thread_cpu_time_enabled(jboolean flag) +{ + thread_cpu_time_enabled = THREAD_CPU_TIME_SUPPORTED ? flag : 0; +} // jthread_set_thread_cpu_time_enabled diff --git a/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp b/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp index 08dbe0f..fe4165b 100644 --- a/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp +++ b/vm/vmcore/src/util/em64t/base/native_stack_em64t.cpp @@ -184,7 +184,7 @@ bool native_unwind_special(native_module_t* modules, void native_unwind_interrupted_frame(VM_thread* pthread, void** p_ip, void** p_bp, void** p_sp) { - Registers* pregs = &pthread->jvmti_saved_exception_registers; + Registers* pregs = (Registers*)(pthread->jvmti_saved_exception_registers); *p_ip = (void*)pregs->rip; *p_bp = (void*)pregs->rbp; *p_sp = (void*)pregs->rsp; diff --git a/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp b/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp index e34f377..e4603d5 100644 --- a/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp +++ b/vm/vmcore/src/util/ia32/base/native_stack_ia32.cpp @@ -185,7 +185,7 @@ bool native_unwind_special(native_module_t* modules, void native_unwind_interrupted_frame(VM_thread* pthread, void** p_ip, void** p_bp, void** p_sp) { - Registers* pregs = &pthread->jvmti_saved_exception_registers; + Registers* pregs = (Registers*)(pthread->jvmti_saved_exception_registers); *p_ip = (void*)pregs->eip; *p_bp = (void*)pregs->ebp; *p_sp = (void*)pregs->esp; diff --git a/vm/vmcore/src/util/ipf/base/ini_ipf.cpp b/vm/vmcore/src/util/ipf/base/ini_ipf.cpp index 2d4ad22..b67fa5b 100644 --- a/vm/vmcore/src/util/ipf/base/ini_ipf.cpp +++ b/vm/vmcore/src/util/ipf/base/ini_ipf.cpp @@ -254,7 +254,7 @@ JIT_execute_method_default(JIT_Handle jh, void *thread_pointer, uint64 tid) = (uint64 (__cdecl * )(void *entry_point, int nargs, uint64 args[], double *double_result_addr, int double_nargs, double double_args[], void *thread_pointer, uint64 tid))&fptr; - IDATA id = hythread_get_id(hythread_self()); + IDATA id = hythread_get_self_id(); uint64 int_result = (uint64)fpp_exec(entry_point, nargs, arg_words, &double_result, double_nargs, double_args, p_TLS_vmthread, id); diff --git a/vm/vmcore/src/util/linux/signals_ia32.cpp b/vm/vmcore/src/util/linux/signals_ia32.cpp index a1351ca..bf079ca 100644 --- a/vm/vmcore/src/util/linux/signals_ia32.cpp +++ b/vm/vmcore/src/util/linux/signals_ia32.cpp @@ -762,7 +762,7 @@ void general_signal_handler(int signum, siginfo_t* info, void* context) assert(signum != SIGTRAP); replaced = true; - new_eip = p_TLS_vmthread->jvmti_saved_exception_registers.eip; + new_eip = (uint32)vm_get_ip_from_regs(p_TLS_vmthread); uc->uc_mcontext.gregs[REG_EIP] = (greg_t)new_eip; } diff --git a/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp b/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp index e6812e4..e7e65db 100644 --- a/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp +++ b/vm/vmcore/src/util/win/ia32_em64t/nt_exception_filter_common.cpp @@ -217,7 +217,10 @@ void __cdecl exception_catch_callback_wrapper(){ // exception catch support for JVMTI void __cdecl jvmti_exception_catch_callback_wrapper(){ - Registers regs = p_TLS_vmthread->regs; + Registers regs = {0}; + if (p_TLS_vmthread->regs) { + regs = *(Registers*)p_TLS_vmthread->regs; + } jvmti_exception_catch_callback(®s); } @@ -247,7 +250,7 @@ LONG NTAPI vectored_exception_handler_internal(LPEXCEPTION_POINTERS nt_exception saved_eip < break_buf + 50) { flag_replaced = true; - regs.set_ip(vmthread->jvmti_saved_exception_registers.get_ip()); + regs.set_ip(vm_get_ip_from_regs(vmthread)); vm_to_nt_context(®s, context); } @@ -370,7 +373,7 @@ LONG NTAPI vectored_exception_handler_internal(LPEXCEPTION_POINTERS nt_exception // save register context of hardware exception site // into thread-local registers snapshot - vmthread->regs = regs; + vm_set_exception_registers(vmthread, regs); // __cdecl <=> push parameters in the reversed order // push in_java argument onto stack @@ -396,7 +399,12 @@ void __cdecl c_exception_handler(Class* exn_class, bool in_java) // this exception handler is executed *after* NT exception handler returned DebugUtilsTI* ti = VM_Global_State::loader_env->TI; // Create local copy for registers because registers in TLS can be changed - Registers regs = p_TLS_vmthread->regs; + Registers regs = {0}; + VM_thread *thread = p_TLS_vmthread; + assert(thread); + if (thread->regs) { + regs = *(Registers*)thread->regs; + } M2nFrame* prev_m2n = m2n_get_last_frame(); M2nFrame* m2n = NULL; @@ -412,7 +420,7 @@ void __cdecl c_exception_handler(Class* exn_class, bool in_java) regs_push_return_address(®s, regs.get_ip()); // Set IP to callback address regs.set_ip(asm_jvmti_exception_catch_callback); - } else if (p_TLS_vmthread->restore_guard_page) { + } else if (thread->restore_guard_page) { // Set return address to current IP regs_push_return_address(®s, regs.get_ip()); // Set IP to callback address @@ -425,7 +433,7 @@ void __cdecl c_exception_handler(Class* exn_class, bool in_java) if (m2n) STD_FREE(m2n); - p_TLS_vmthread->regs = regs; + vm_set_exception_registers(thread, regs); si_transfer_control(si); assert(!"si_transfer_control should not return"); }