Index: vm/include/open/ti_thread.h =================================================================== --- vm/include/open/ti_thread.h (revision 508380) +++ vm/include/open/ti_thread.h (working copy) @@ -64,6 +64,7 @@ IDATA jthread_get_thread_count(jint *count); IDATA jthread_get_blocked_count(jint* count); IDATA jthread_get_waited_count(jint* count); +IDATA jthread_get_total_started_thread_count(jint* count); //@} /** @name Local storage @@ -85,6 +86,10 @@ IDATA jthread_get_lock_recursion(jobject monitor, jthread lock_owner); IDATA jthread_get_owned_monitors(jthread thread, jint* mon_count_ptr, jobject** monitors); +jboolean jthread_is_thread_contention_monitoring_enabled(); +jboolean jthread_is_thread_contention_monitoring_supported(); +void jthread_set_thread_contention_monitoring_enabled(jboolean flag); + //@} /** @name CPU timing */ @@ -96,6 +101,15 @@ IDATA jthread_get_thread_waited_time(jthread thread, jlong *nanos_ptr); IDATA jthread_get_thread_cpu_timer_info(jvmtiTimerInfo* info_ptr); +jlong jthread_get_thread_blocked_times_count(jthread java_thread); +jlong jthread_get_thread_waited_times_count(jthread java_thread); + +jboolean jthread_is_current_thread_cpu_time_supported(); +jboolean jthread_is_thread_cpu_time_enabled(); +jboolean jthread_is_thread_cpu_time_supported(); + +void jthread_set_thread_cpu_time_enabled(jboolean flag); + //@} /** @name Peak count */ Index: vm/vmcore/src/kernel_classes/native/org_apache_harmony_lang_management_ThreadMXBeanImpl.cpp =================================================================== --- vm/vmcore/src/kernel_classes/native/org_apache_harmony_lang_management_ThreadMXBeanImpl.cpp (revision 508380) +++ vm/vmcore/src/kernel_classes/native/org_apache_harmony_lang_management_ThreadMXBeanImpl.cpp (working copy) @@ -33,6 +33,7 @@ #include "environment.h" #include "java_lang_System.h" #include "org_apache_harmony_lang_management_ThreadMXBeanImpl.h" +#include "open/jthread.h" /* Native methods */ @@ -40,12 +41,51 @@ * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.findMonitorDeadlockedThreadsImpl()[J */ JNIEXPORT jlongArray JNICALL -Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_findMonitorDeadlockedThreadsImpl(JNIEnv *jenv, jobject) +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_findMonitorDeadlockedThreadsImpl +(JNIEnv *jenv_ext, jobject) { - // TODO implement this method stub correctly - TRACE2("management","findMonitorDeadlockedThreadsImpl stub invocation"); - jlongArray array = jenv->NewLongArray(0); + TRACE2("management", "findMonitorDeadlockedThreadsImpl invocation"); + JNIEnv_Internal *jenv = (JNIEnv_Internal *)jenv_ext; + jthread* threads; + jthread* dead_threads; + jint count; + jint dead_count; + IDATA UNUSED status = jthread_get_all_threads(&threads, &count); + assert(!status); + + status = jthread_get_deadlocked_threads(threads, count, &dead_threads, &dead_count); + assert(!status); + + free(threads); + if (dead_count == 0){ + return NULL; + } + + jlong* ids = (jlong*)malloc(sizeof(jlong)* dead_count); + assert(ids); + + jclass cl = jenv->FindClass("java/lang/Thread"); + if (jenv->ExceptionCheck()) return NULL; + + jmethodID mid = jenv->GetMethodID(cl, "getId","()J"); + if (jenv->ExceptionCheck()) return NULL; + + for (int i = 0; i < dead_count; i++){ + ids[i] = jenv->CallLongMethod(dead_threads[i], mid); + if (jenv->ExceptionCheck()) return NULL; + } + + free(dead_threads); + + jlongArray array = jenv->NewLongArray(dead_count); + if (jenv->ExceptionCheck()) return NULL; + + jenv->SetLongArrayRegion(array, 0, dead_count, ids); + if (jenv->ExceptionCheck()) return NULL; + + free(ids); + return array; }; @@ -53,32 +93,39 @@ * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getAllThreadIdsImpl()[J */ JNIEXPORT jlongArray JNICALL -Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getAllThreadIdsImpl(JNIEnv *jenv_ext, jobject) +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getAllThreadIdsImpl +(JNIEnv *jenv_ext, jobject) { - // TODO implement this method stub correctly - TRACE2("management","getAllThreadIdsImpl stub invocation"); + TRACE2("management", "getAllThreadIdsImpl invocation"); JNIEnv_Internal *jenv = (JNIEnv_Internal *)jenv_ext; + jthread* threads; + jint count; - jlongArray array = jenv->NewLongArray(1); - if (jenv->ExceptionCheck()) return NULL; + IDATA UNUSED status = jthread_get_all_threads(&threads, &count); + assert(!status); + jlong* ids = (jlong*)malloc(sizeof(jlong)* count); + assert(ids); - jclass threadClazz =jenv->FindClass("java/lang/Thread"); + jclass cl =jenv->FindClass("java/lang/Thread"); if (jenv->ExceptionCheck()) return NULL; - jmethodID currentThreadMethod = jenv->GetStaticMethodID(threadClazz, "currentThread", - "()Ljava/lang/Thread;"); + jmethodID mid = jenv->GetMethodID(cl, "getId","()J"); if (jenv->ExceptionCheck()) return NULL; - jobject currentThread = jenv->CallStaticObjectMethod(threadClazz, currentThreadMethod, NULL); - if (jenv->ExceptionCheck()) return NULL; + for (int i = 0; i < count; i++){ + ids[i] = jenv->CallLongMethod(threads[i], mid); + if (jenv->ExceptionCheck()) return NULL; + } - jmethodID getIdMethod = jenv->GetMethodID(threadClazz, "getId", "()J"); + free(threads); + + jlongArray array = jenv->NewLongArray(count); if (jenv->ExceptionCheck()) return NULL; - jlong id = jenv->CallLongMethod(currentThread, getIdMethod); + jenv->SetLongArrayRegion(array, 0, count, ids); if (jenv->ExceptionCheck()) return NULL; - jenv->SetLongArrayRegion(array, 0, 1, &id); + free(ids); return array; }; @@ -87,11 +134,30 @@ * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getDaemonThreadCountImpl()I */ JNIEXPORT jint JNICALL -Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getDaemonThreadCountImpl(JNIEnv *, jobject) +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getDaemonThreadCountImpl(JNIEnv *jenv, jobject) { - // TODO implement this method stub correctly - TRACE2("management","getDaemonThreadCountImpl stub invocation"); - return 0; + jthread* threads; + jint count; + jint daemon_count = 0; + + TRACE2("management", "getDaemonThreadCountImpl invocation"); + IDATA UNUSED status = jthread_get_all_threads(&threads, &count); + assert(!status); + + jclass cl = jenv->FindClass("java/lang/Thread"); + if (jenv->ExceptionCheck()) return 0; + jmethodID id = jenv->GetMethodID(cl, "isDaemon","()Z"); + if (jenv->ExceptionCheck()) return 0; + + for (int i = 0; i < count; i++){ + int is_daemon = jenv->CallBooleanMethod(threads[i], id); + if (jenv->ExceptionCheck()) return 0; + if (is_daemon){ + daemon_count++; + } + } + free(threads); + return daemon_count; }; /* @@ -100,9 +166,11 @@ JNIEXPORT jint JNICALL Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getPeakThreadCountImpl(JNIEnv *, jobject) { - // TODO implement this method stub correctly - TRACE2("management","getPeakThreadCountImpl stub invocation"); - return 1; + jint count = 0; + TRACE2("management", "getPeakThreadCountImpl invocation"); + IDATA UNUSED status = jthread_get_peak_thread_count(&count); + assert(!status); + return count; }; /* @@ -111,26 +179,31 @@ JNIEXPORT jint JNICALL Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadCountImpl(JNIEnv *, jobject) { - // TODO implement this method stub correctly - TRACE2("management","getThreadCountImpl stub invocation"); - return 1; + jint count; + TRACE2("management", "getThreadCountImpl invocation"); + IDATA UNUSED status = jthread_get_thread_count(&count); + assert(!status); + return count; }; /* * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadCpuTimeImpl(J)J */ JNIEXPORT jlong JNICALL -Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadCpuTimeImpl(JNIEnv *jenv, jobject, - jlong id) +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadCpuTimeImpl +(JNIEnv * jenv_ext, jobject obj, jlong thread_id) { - // TODO implement this method stub correctly - TRACE2("management","getThreadCpuTimeImpl stub invocation"); - if (id <= 0) { - TRACE2("management","getThreadCpuTimeImpl java/lang/IllegalArgumentException is thrown"); - ThrowNew_Quick(jenv, "java/lang/IllegalArgumentException", "id <= 0"); - }; - - return 1L<<10; + JNIEnv_Internal *jenv = (JNIEnv_Internal *)jenv_ext; + jlong nanos; + TRACE2("management", "getThreadCpuTimeImpl invocation"); + jthread thread = Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadByIdImpl(jenv_ext, obj, thread_id); + if (jenv->ExceptionCheck()) return 0; + if (! thread){ + return -1; + } + IDATA UNUSED status = jthread_get_thread_cpu_time(thread, &nanos); + assert(status == TM_ERROR_NONE); + return nanos; }; /* @@ -138,24 +211,40 @@ */ JNIEXPORT jobject JNICALL Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadByIdImpl( - JNIEnv *jenv_ext, + JNIEnv * jenv_ext, jobject, - jlong) + jlong thread_id) { - // TODO implement this method stub correctly - TRACE2("management","getThreadByIdImpl stub invocation"); + TRACE2("management", "getThreadByIdImpl invocation"); JNIEnv_Internal *jenv = (JNIEnv_Internal *)jenv_ext; + jthread* threads; + jint count; + jlong id; + jobject res = NULL; - jclass threadClazz =jenv->FindClass("java/lang/Thread"); + IDATA UNUSED status = jthread_get_all_threads(&threads, &count); + assert(!status); + + jclass cl =jenv->FindClass("java/lang/Thread"); if (jenv->ExceptionCheck()) return NULL; - jmethodID currentThreadMethod = jenv->GetStaticMethodID(threadClazz, "currentThread", - "()Ljava/lang/Thread;"); + jmethodID jmid = jenv->GetMethodID(cl, "getId","()J"); if (jenv->ExceptionCheck()) return NULL; - jobject jresult = jenv->CallStaticObjectMethod(threadClazz, currentThreadMethod, NULL); - return jresult; + for (int i = 0; i < count; i++){ + id = jenv->CallLongMethod(threads[i], jmid); + if (jenv->ExceptionCheck()) return NULL; + + if (id == thread_id){ + res = jenv->NewGlobalRef(threads[i]); + break; + } + } + + free(threads); + + return res; }; /* @@ -163,11 +252,18 @@ */ JNIEXPORT jobject JNICALL Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getObjectThreadIsBlockedOnImpl(JNIEnv *, jobject, - jobject) + jobject thread) { - // TODO implement this method stub correctly - TRACE2("management","getObjectThreadIsBlockedOnImpl stub invocation"); - return NULL; + jobject monitor; + TRACE2("management", "getObjectThreadIsBlockedOnImpl invocation"); + IDATA UNUSED status = jthread_get_contended_monitor(thread, &monitor); + assert(!status); + if (monitor){ + return monitor; + } + status = jthread_get_wait_monitor(thread, &monitor); + assert(!status); + return monitor; }; /* @@ -175,11 +271,13 @@ */ JNIEXPORT jobject JNICALL Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadOwningObjectImpl(JNIEnv *, jobject, - jobject) + jobject monitor) { - // TODO implement this method stub correctly - TRACE2("management","getThreadOwningObjectImpl stub invocation"); - return NULL; + jthread lock_owner; + TRACE2("management", "getThreadOwningObjectImpl invocation"); + IDATA UNUSED status = jthread_get_lock_owner(monitor, &lock_owner); + assert(!status); + return lock_owner; }; /* @@ -187,11 +285,13 @@ */ JNIEXPORT jboolean JNICALL Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isSuspendedImpl(JNIEnv *, jobject, - jobject) + jobject thread) { - // TODO implement this method stub correctly - TRACE2("management","ThreadMXBeanImpl_isSuspendedImpl stub invocation"); - return JNI_TRUE; + jint thread_state; + TRACE2("management", "ThreadMXBeanImpl_isSuspendedImpl invocation"); + IDATA UNUSED status = jthread_get_state(thread, &thread_state); + assert(!status); + return thread_state & TM_THREAD_STATE_SUSPENDED; }; /* @@ -199,11 +299,10 @@ */ JNIEXPORT jlong JNICALL Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadWaitedCountImpl(JNIEnv *, jobject, - jobject) + jobject thread) { - // TODO implement this method stub correctly - TRACE2("management","getThreadWaitedCountImpl stub invocation"); - return 2L; + TRACE2("management", "getThreadWaitedCountImpl invocation"); + return jthread_get_thread_waited_times_count(thread); }; /* @@ -211,11 +310,13 @@ */ JNIEXPORT jlong JNICALL Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadWaitedTimeImpl(JNIEnv *, jobject, - jobject) + jobject thread) { - // TODO implement this method stub correctly - TRACE2("management","getThreadWaitedCountImpl stub invocation"); - return 1L<<12; + jlong nanos; + TRACE2("management", "getThreadWaitedCountImpl invocation"); + IDATA UNUSED status = jthread_get_thread_waited_time(thread, &nanos); + assert(status == TM_ERROR_NONE); + return nanos; }; /* @@ -223,11 +324,13 @@ */ JNIEXPORT jlong JNICALL Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadBlockedTimeImpl(JNIEnv *, jobject, - jobject) + jobject thread) { - // TODO implement this method stub correctly - TRACE2("management","getThreadBlockedTimeImpl stub invocation"); - return 1L<<11; + jlong nanos; + TRACE2("management", "getThreadBlockedTimeImpl invocation"); + IDATA UNUSED status = jthread_get_thread_blocked_time(thread, &nanos); + assert(status == TM_ERROR_NONE); + return nanos; }; /* @@ -235,11 +338,10 @@ */ JNIEXPORT jlong JNICALL Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadBlockedCountImpl(JNIEnv *, jobject, - jobject) + jobject thread) { - // TODO implement this method stub correctly - TRACE2("management","getThreadBlockedCountImpl stub invocation"); - return 5L; + TRACE2("management", "getThreadBlockedCountImpl invocation"); + return jthread_get_thread_blocked_times_count(thread); }; /* @@ -263,11 +365,9 @@ jstring lockOwnerNameVal, jobjectArray stackTraceVal) { - // TODO implement this method stub correctly - TRACE2("management","createThreadInfoImpl stub invocation"); - JNIEnv_Internal *jenv = (JNIEnv_Internal *)jenv_ext; + TRACE2("management", "createThreadInfoImpl invocation"); jclass threadInfoClazz =jenv->FindClass("java/lang/management/ThreadInfo"); if (jenv->ExceptionCheck()) return NULL; jmethodID threadInfoClazzConstructor = jenv->GetMethodID(threadInfoClazz, "", @@ -292,8 +392,6 @@ lockOwnerNameVal, stackTraceVal); - assert(!exn_raised()); - return threadInfo; }; @@ -301,12 +399,20 @@ * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadUserTimeImpl(J)J */ JNIEXPORT jlong JNICALL -Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadUserTimeImpl(JNIEnv *, jobject, - jlong) +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadUserTimeImpl +(JNIEnv * jenv_ext, jobject obj, jlong threadId) { - // TODO implement this method stub correctly - TRACE2("management","getThreadUserTimeImpl stub invocation"); - return 1L<<11; + TRACE2("management", "getThreadUserTimeImpl invocation"); + JNIEnv_Internal *jenv = (JNIEnv_Internal *)jenv_ext; + jlong nanos; + jthread thread = Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadByIdImpl(jenv_ext, obj, threadId); + if (jenv->ExceptionCheck()) return 0; + if (! thread){ + return -1; + } + IDATA UNUSED status = jthread_get_thread_user_cpu_time(thread, &nanos); + assert(status == TM_ERROR_NONE); + return nanos; }; /* @@ -315,9 +421,11 @@ JNIEXPORT jlong JNICALL Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getTotalStartedThreadCountImpl(JNIEnv *, jobject) { - // TODO implement this method stub correctly - TRACE2("management","getTotalStartedThreadCountImpl stub invocation"); - return 5L; + jint count; + TRACE2("management", "getTotalStartedThreadCountImpl invocation"); + IDATA UNUSED status = jthread_get_total_started_thread_count(&count); + assert(status == TM_ERROR_NONE); + return count; }; /* @@ -326,22 +434,18 @@ JNIEXPORT jboolean JNICALL Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isCurrentThreadCpuTimeSupportedImpl(JNIEnv *, jobject) { - // TODO implement this method stub correctly - TRACE2("management","isCurrentThreadCpuTimeSupportedImpl stub invocation"); - return JNI_TRUE; + TRACE2("management", "isCurrentThreadCpuTimeSupportedImpl invocation"); + return jthread_is_current_thread_cpu_time_supported(); }; -jboolean thread_contention_monitoring = JNI_TRUE; - /* * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.isThreadContentionMonitoringEnabledImpl()Z */ JNIEXPORT jboolean JNICALL Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isThreadContentionMonitoringEnabledImpl(JNIEnv *, jobject) { - // TODO implement this method stub correctly - TRACE2("management","isThreadContentionMonitoringEnabledImpl stub invocation"); - return thread_contention_monitoring; + TRACE2("management", "isThreadContentionMonitoringEnabledImpl invocation"); + return jthread_is_thread_contention_monitoring_enabled(); }; /* @@ -350,22 +454,18 @@ JNIEXPORT jboolean JNICALL Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isThreadContentionMonitoringSupportedImpl(JNIEnv *, jobject) { - // TODO implement this method stub correctly - TRACE2("management","isThreadContentionMonitoringSupportedImpl stub invocation"); - return JNI_TRUE; + TRACE2("management", "isThreadContentionMonitoringSupportedImpl invocation"); + return jthread_is_thread_contention_monitoring_supported(); }; -jboolean thread_cpu_time_enabled = JNI_TRUE; - /* * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.isThreadCpuTimeEnabledImpl()Z */ JNIEXPORT jboolean JNICALL Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isThreadCpuTimeEnabledImpl(JNIEnv *, jobject) { - // TODO implement this method stub correctly - TRACE2("management","isThreadCpuTimeEnabledImpl stub invocation"); - return thread_cpu_time_enabled; + TRACE2("management", "isThreadCpuTimeEnabledImpl invocation"); + return jthread_is_thread_cpu_time_enabled(); }; /* @@ -374,9 +474,8 @@ JNIEXPORT jboolean JNICALL Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isThreadCpuTimeSupportedImpl(JNIEnv *, jobject) { - // TODO implement this method stub correctly - TRACE2("management","isThreadCpuTimeSupportedImpl stub invocation"); - return JNI_TRUE; + TRACE2("management", "isThreadCpuTimeSupportedImpl invocation"); + return jthread_is_thread_cpu_time_supported(); }; /* @@ -385,8 +484,9 @@ JNIEXPORT void JNICALL Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_resetPeakThreadCountImpl(JNIEnv *, jobject) { - // TODO implement this method stub correctly - TRACE2("management","resetPeakThreadCountImpl stub invocation"); + TRACE2("management", "resetPeakThreadCountImpl invocation"); + IDATA UNUSED status = jthread_reset_peak_thread_count(); + assert(status == TM_ERROR_NONE); }; /* @@ -399,8 +499,8 @@ jboolean new_value) { // TODO implement this method stub correctly - TRACE2("management","setThreadContentionMonitoringEnabledImpl stub invocation"); - thread_contention_monitoring = new_value; + TRACE2("management", "setThreadContentionMonitoringEnabledImpl invocation"); + jthread_set_thread_contention_monitoring_enabled(new_value); }; /* @@ -410,9 +510,8 @@ Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_setThreadCpuTimeEnabledImpl(JNIEnv *, jobject, jboolean new_value) { - // TODO implement this method stub correctly - TRACE2("management","setThreadCpuTimeEnabledImpl stub invocation"); - thread_cpu_time_enabled = new_value; + TRACE2("management", "setThreadCpuTimeEnabledImpl invocation"); + jthread_set_thread_cpu_time_enabled(new_value); }; Index: vm/thread/src/thread_ti_instr.c =================================================================== --- vm/thread/src/thread_ti_instr.c (revision 508380) +++ vm/thread/src/thread_ti_instr.c (working copy) @@ -221,6 +221,16 @@ } /** + * 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; +} + +/** * Returns the number of blocked threads. * * @param[out] count_ptr number of threads. Index: vm/thread/src/thread_private.h =================================================================== --- vm/thread/src/thread_private.h (revision 508380) +++ vm/thread/src/thread_private.h (working copy) @@ -344,11 +344,21 @@ 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; @@ -559,6 +569,7 @@ extern int max_group_index; // max number of groups +extern int total_started_thread_count; // Total started thread counter. #define THREAD_ID_SIZE 16 //size of thread ID in bits. Also defines max number of threads @@ -633,6 +644,11 @@ 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(); #ifdef __cplusplus Index: vm/thread/src/thread_java_basic.c =================================================================== --- vm/thread/src/thread_java_basic.c (revision 508380) +++ vm/thread/src/thread_java_basic.c (working copy) @@ -85,6 +85,8 @@ // Send Thread Start event. jvmti_send_thread_start_end_event(1); + + thread_start_count(); if (data->tiProc != NULL) { data->tiProc(data->tiEnv, jni_env, data->tiProcArgs); @@ -206,6 +208,8 @@ // Send Thread Start event. jvmti_send_thread_start_end_event(1); + thread_start_count(); + TRACE(("TM: Current thread attached to jthread=%p", java_thread)); return TM_ERROR_NONE; } @@ -280,6 +284,8 @@ // jthread_self() will return NULL now. tm_jvmti_thread->thread_object = NULL; + // Decrease alive thread counter + thread_end_count(); // Deallocate tm_jvmti_thread //apr_pool_destroy(tm_jvmti_thread->pool); @@ -317,6 +323,10 @@ tm_java_thread->thread_ref = (thread_ref) ? (*jni_env)->NewGlobalRef(jni_env, 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; Index: vm/thread/src/thread_ti_timing.c =================================================================== --- vm/thread/src/thread_ti_timing.c (revision 508380) +++ vm/thread/src/thread_ti_timing.c (working copy) @@ -26,6 +26,13 @@ #include "thread_private.h" #include "apr_thread_ext.h" +#define THREAD_CPU_TIME_SUPPORTED 1 + +/* + * Thread CPU time enabled flag. + */ +int thread_cpu_time_enabled = 0; + /** * Returns time spent by the specific thread while contending for monitors. * @@ -116,3 +123,68 @@ return TM_ERROR_NONE; } + +/** + * Returns number of times the specific thread contending for monitors. + * + * @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 = hythread_get_private_data(tm_native_thread); + + return tm_java_thread->blocked_count; +} + +/** + * Returns number of times the specific thread waiting on monitors for notification. + * + * @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 = hythread_get_private_data(tm_native_thread); + + return tm_java_thread->waited_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(){ + return 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(){ + return THREAD_CPU_TIME_SUPPORTED; +} + +/** + * Returns true if VM supports (current) thread CPU and USER time requests and + * this feature is enabled + * + * @return true if thread CPU and USER time requests are enabled, false otherwise; + */ +jboolean jthread_is_thread_cpu_time_enabled(){ + return 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; +} Index: vm/thread/src/thread_ti_others.c =================================================================== --- vm/thread/src/thread_ti_others.c (revision 508380) +++ vm/thread/src/thread_ti_others.c (working copy) @@ -25,14 +25,34 @@ #include #include "thread_private.h" +#define THREAD_CONTENTION_MONITORING_SUPPORTED 1 + /* + * Monitors contentions requests enabled flag. + */ +int thread_contention_monitoring_enabled = 0; + +/* + * Total started thread counter. + */ +int total_started_thread_count = 0; + +/* + * Alive thread counter. + */ +int alive_thread_count = 0; + +/* * Peak count */ +int peak_thread_count = 0; /** - * Resets the thread peak counter. + * Resets the thread peak counter to current value. */ IDATA jthread_reset_peak_thread_count () { + + peak_thread_count = alive_thread_count; return TM_ERROR_NONE; } @@ -40,10 +60,41 @@ * Returns the peak thread count since the last peak reset. */ IDATA jthread_get_peak_thread_count (jint *threads_count_ptr) { + *threads_count_ptr = peak_thread_count; return TM_ERROR_NONE; -} +} + +/** + * 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(){ + return 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(){ + + return 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; +} + +/** * Returns JVMTILocalStorage pointer. * * @param[in] java_thread @@ -59,3 +110,22 @@ return &tm_java_thread->jvmti_local_storage; } + +/** + * Increase thread counters. + */ +void thread_start_count(){ + alive_thread_count++; + total_started_thread_count++; + if (peak_thread_count < alive_thread_count) { + peak_thread_count = alive_thread_count; + } +} + +/** + * Decrease alive thread counter. + */ +void thread_end_count(){ + alive_thread_count--; +} +