Index: vm/include/open/ti_thread.h =================================================================== --- vm/include/open/ti_thread.h (revision 462806) +++ vm/include/open/ti_thread.h (working copy) @@ -66,6 +66,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 @@ -87,6 +88,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 */ @@ -98,6 +103,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/include/open/jthread.h =================================================================== --- vm/include/open/jthread.h (revision 462806) +++ vm/include/open/jthread.h (working copy) @@ -125,6 +125,7 @@ IDATA jthread_set_priority(jthread thread, int priority); int jthread_get_priority(jthread thread); +jlong jthread_get_thread_id(jthread thread); jboolean jthread_is_daemon(jthread thread); /** Index: vm/vmcore/include/version_svn_tag.h =================================================================== --- vm/vmcore/include/version_svn_tag.h (revision 462806) +++ vm/vmcore/include/version_svn_tag.h (working copy) @@ -18,6 +18,6 @@ #ifndef _VERSION_SVN_TAG_ #define _VERSION_SVN_TAG_ -#define VERSION_SVN_TAG "454528" +#define VERSION_SVN_TAG "462806" #endif // _VERSION_SVN_TAG_ Index: vm/vmcore/src/kernel_classes/native/org_apache_harmony_lang_management_ThreadMXBeanImpl.h =================================================================== --- vm/vmcore/src/kernel_classes/native/org_apache_harmony_lang_management_ThreadMXBeanImpl.h (revision 0) +++ vm/vmcore/src/kernel_classes/native/org_apache_harmony_lang_management_ThreadMXBeanImpl.h (revision 0) @@ -0,0 +1,219 @@ +/* + * 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. + */ +/* + * THE FILE HAS BEEN AUTOGENERATED BY THE IJH TOOL. + * Please be aware that all changes made to this file manually + * will be overwritten by the tool if it runs again. + */ + +#include + + +/* Header for class org.apache.harmony.lang.management.ThreadMXBeanImpl */ + +#ifndef _ORG_APACHE_HARMONY_LANG_MANAGEMENT_THREADMXBEANIMPL_H +#define _ORG_APACHE_HARMONY_LANG_MANAGEMENT_THREADMXBEANIMPL_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Static final fields */ + +#undef org_apache_harmony_lang_management_ThreadMXBeanImpl_TM_ERROR_NONE +#define org_apache_harmony_lang_management_ThreadMXBeanImpl_TM_ERROR_NONE 0L + +#undef org_apache_harmony_lang_management_ThreadMXBeanImpl_TM_ERROR_INTERRUPT +#define org_apache_harmony_lang_management_ThreadMXBeanImpl_TM_ERROR_INTERRUPT 52L + +#undef org_apache_harmony_lang_management_ThreadMXBeanImpl_TM_ERROR_ILLEGAL_STATE +#define org_apache_harmony_lang_management_ThreadMXBeanImpl_TM_ERROR_ILLEGAL_STATE 118L + + +/* Native methods */ + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.findMonitorDeadlockedThreadsImpl()[J + */ +JNIEXPORT jlongArray JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_findMonitorDeadlockedThreadsImpl(JNIEnv *, jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getAllThreadIdsImpl()[J + */ +JNIEXPORT jlongArray JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getAllThreadIdsImpl(JNIEnv *, jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getDaemonThreadCountImpl()I + */ +JNIEXPORT jint JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getDaemonThreadCountImpl(JNIEnv *, jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getPeakThreadCountImpl()I + */ +JNIEXPORT jint JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getPeakThreadCountImpl(JNIEnv *, jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadCountImpl()I + */ +JNIEXPORT jint JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadCountImpl(JNIEnv *, jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadCpuTimeImpl(J)J + */ +JNIEXPORT jlong JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadCpuTimeImpl(JNIEnv *, jobject, + jlong); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadByIdImpl(J)Ljava/lang/Thread; + */ +JNIEXPORT jobject JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadByIdImpl(JNIEnv *, jobject, + jlong); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getObjectThreadIsBlockedOnImpl(Ljava/lang/Thread;)Ljava/lang/Object; + */ +JNIEXPORT jobject JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getObjectThreadIsBlockedOnImpl(JNIEnv *, jobject, + jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadOwningObjectImpl(Ljava/lang/Object;)Ljava/lang/Thread; + */ +JNIEXPORT jobject JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadOwningObjectImpl(JNIEnv *, jobject, + jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.isSuspendedImpl(Ljava/lang/Thread;)Z + */ +JNIEXPORT jboolean JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isSuspendedImpl(JNIEnv *, jobject, + jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadWaitedCountImpl(Ljava/lang/Thread;)J + */ +JNIEXPORT jlong JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadWaitedCountImpl(JNIEnv *, jobject, + jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadWaitedTimeImpl(Ljava/lang/Thread;)J + */ +JNIEXPORT jlong JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadWaitedTimeImpl(JNIEnv *, jobject, + jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadBlockedTimeImpl(Ljava/lang/Thread;)J + */ +JNIEXPORT jlong JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadBlockedTimeImpl(JNIEnv *, jobject, + jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadBlockedCountImpl(Ljava/lang/Thread;)J + */ +JNIEXPORT jlong JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadBlockedCountImpl(JNIEnv *, jobject, + jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.createThreadInfoImpl(JLjava/lang/String;Ljava/lang/Thread$State;ZZJJJJLjava/lang/String;JLjava/lang/String;[Ljava/lang/StackTraceElement;)Ljava/lang/management/ThreadInfo; + */ +JNIEXPORT jobject JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_createThreadInfoImpl(JNIEnv *, jobject, + jlong, jstring, jobject, jboolean, jboolean, jlong, jlong, jlong, jlong, jstring, jlong, jstring, jobjectArray); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadUserTimeImpl(J)J + */ +JNIEXPORT jlong JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadUserTimeImpl(JNIEnv *, jobject, + jlong); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getTotalStartedThreadCountImpl()J + */ +JNIEXPORT jlong JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getTotalStartedThreadCountImpl(JNIEnv *, jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.isCurrentThreadCpuTimeSupportedImpl()Z + */ +JNIEXPORT jboolean JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isCurrentThreadCpuTimeSupportedImpl(JNIEnv *, jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.isThreadContentionMonitoringEnabledImpl()Z + */ +JNIEXPORT jboolean JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isThreadContentionMonitoringEnabledImpl(JNIEnv *, jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.isThreadContentionMonitoringSupportedImpl()Z + */ +JNIEXPORT jboolean JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isThreadContentionMonitoringSupportedImpl(JNIEnv *, jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.isThreadCpuTimeEnabledImpl()Z + */ +JNIEXPORT jboolean JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isThreadCpuTimeEnabledImpl(JNIEnv *, jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.isThreadCpuTimeSupportedImpl()Z + */ +JNIEXPORT jboolean JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isThreadCpuTimeSupportedImpl(JNIEnv *, jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.resetPeakThreadCountImpl()V + */ +JNIEXPORT void JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_resetPeakThreadCountImpl(JNIEnv *, jobject); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.setThreadContentionMonitoringEnabledImpl(Z)V + */ +JNIEXPORT void JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_setThreadContentionMonitoringEnabledImpl(JNIEnv *, jobject, + jboolean); + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.setThreadCpuTimeEnabledImpl(Z)V + */ +JNIEXPORT void JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_setThreadCpuTimeEnabledImpl(JNIEnv *, jobject, + jboolean); + + +#ifdef __cplusplus +} +#endif + +#endif /* _ORG_APACHE_HARMONY_LANG_MANAGEMENT_THREADMXBEANIMPL_H */ + 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 0) +++ vm/vmcore/src/kernel_classes/native/org_apache_harmony_lang_management_ThreadMXBeanImpl.cpp (revision 0) @@ -0,0 +1,469 @@ +/* + * 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. + */ +/** + * @author Andrey Yakushev + * @version $Revision$ + */ + +/** + * @file org_apache_harmony_lang_management_ThreadMXBeanImpl.cpp + * + * This file is a part of kernel class natives VM core component. + * It contains implementation for native methods of + * org.apache.harmony.lang.management.ThreadMXBeanImpl class. + */ + +#include +#include +#include "exceptions.h" +#include "environment.h" +#include "java_lang_System.h" +#include "org_apache_harmony_lang_management_ThreadMXBeanImpl.h" +#include "open/jthread.h" + +/* Native methods */ + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.findMonitorDeadlockedThreadsImpl()[J + */ +JNIEXPORT jlongArray JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_findMonitorDeadlockedThreadsImpl(JNIEnv *jenv, jobject) +{ + jthread* threads; + jthread* dead_threads; + jint count; + jint dead_count; + + TRACE2("management","findMonitorDeadlockedThreadsImpl invocation"); + IDATA UNUSED status = jthread_get_all_threads(&threads, &count); + assert(!status); + status = jthread_get_deadlocked_threads(threads, count, &dead_threads, &dead_count); + assert(!status); + if (dead_count == 0){ + return NULL; + } + + jlong* ids = (jlong*)malloc(sizeof(jlong)* dead_count); + assert(ids); + + for (int i = 0; i < dead_count; i++){ + ids[i] = jthread_get_thread_id(dead_threads[i]); + } + jlongArray array = jenv->NewLongArray(dead_count); + assert(!jenv->ExceptionCheck()); + jenv->SetLongArrayRegion(array, 0, dead_count, ids); + assert(!jenv->ExceptionCheck()); + free(ids); + + return array; +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getAllThreadIdsImpl()[J + */ +JNIEXPORT jlongArray JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getAllThreadIdsImpl(JNIEnv *jenv, jobject) +{ + jthread* threads; + jint count; + + TRACE2("management","getAllThreadIdsImpl invocation"); + IDATA UNUSED status = jthread_get_all_threads(&threads, &count); + assert(!status); + jlong* ids = (jlong*)malloc(sizeof(jlong)* count); + assert(ids); + + for (int i = 0; i < count; i++){ + ids[i] = jthread_get_thread_id(threads[i]); + } + jlongArray array = jenv->NewLongArray(count); + assert(!jenv->ExceptionCheck()); + jenv->SetLongArrayRegion(array, 0, count, ids); + assert(!jenv->ExceptionCheck()); + free(ids); + + return array; +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getDaemonThreadCountImpl()I + */ +JNIEXPORT jint JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getDaemonThreadCountImpl(JNIEnv *jenv, jobject) +{ + 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"); + assert(!jenv->ExceptionCheck()); + jmethodID id = jenv->GetMethodID(cl, "isDaemon","()Z"); + assert(!jenv->ExceptionCheck()); + + for (int i = 0; i < count; i++){ + int is_daemon = jenv->CallBooleanMethod(threads[i], id); + assert(!jenv->ExceptionCheck()); + if (is_daemon){ + daemon_count++; + } + } + return daemon_count; +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getPeakThreadCountImpl()I + */ +JNIEXPORT jint JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getPeakThreadCountImpl(JNIEnv *, jobject) +{ + jint count = 0; + TRACE2("management","getPeakThreadCountImpl invocation"); + IDATA UNUSED status = jthread_get_peak_thread_count(&count); + assert(!status); + return count; +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadCountImpl()I + */ +JNIEXPORT jint JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadCountImpl(JNIEnv *, jobject) +{ + 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 *, jobject, + jlong thread_id) +{ + jlong nanos; + TRACE2("management","getThreadCpuTimeImpl invocation"); + jthread thread = jthread_get_thread(thread_id); + if (! thread){ + return -1; + } + IDATA UNUSED status = jthread_get_thread_cpu_time(thread, &nanos); + assert(status == TM_ERROR_NONE); + return nanos; +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadByIdImpl(J)Ljava/lang/Thread; + */ +JNIEXPORT jobject JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadByIdImpl( + JNIEnv *, + jobject, + jlong thread_id) +{ + TRACE2("management","getThreadByIdImpl invocation"); + return jthread_get_thread(thread_id); +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getObjectThreadIsBlockedOnImpl(Ljava/lang/Thread;)Ljava/lang/Object; + */ +JNIEXPORT jobject JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getObjectThreadIsBlockedOnImpl(JNIEnv *, jobject, + jobject thread) +{ + 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; +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadOwningObjectImpl(Ljava/lang/Object;)Ljava/lang/Thread; + */ +JNIEXPORT jobject JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadOwningObjectImpl(JNIEnv *, jobject, + jobject monitor) +{ + jthread lock_owner; + TRACE2("management","getThreadOwningObjectImpl invocation"); + IDATA UNUSED status = jthread_get_lock_owner(monitor, &lock_owner); + assert(!status); + return lock_owner; +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.isSuspendedImpl(Ljava/lang/Thread;)Z + */ +JNIEXPORT jboolean JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isSuspendedImpl(JNIEnv *, jobject, + jobject thread) +{ + 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; +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadWaitedCountImpl(Ljava/lang/Thread;)J + */ +JNIEXPORT jlong JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadWaitedCountImpl(JNIEnv *, jobject, + jobject thread) +{ + TRACE2("management","getThreadWaitedCountImpl invocation"); + return jthread_get_thread_waited_times_count(thread); +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadWaitedTimeImpl(Ljava/lang/Thread;)J + */ +JNIEXPORT jlong JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadWaitedTimeImpl(JNIEnv *, jobject, + jobject thread) +{ + jlong nanos; + TRACE2("management","getThreadWaitedCountImpl invocation"); + IDATA UNUSED status = jthread_get_thread_waited_time(thread, &nanos); + assert(status == TM_ERROR_NONE); + return nanos; +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadBlockedTimeImpl(Ljava/lang/Thread;)J + */ +JNIEXPORT jlong JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadBlockedTimeImpl(JNIEnv *, jobject, + jobject thread) +{ + jlong nanos; + TRACE2("management","getThreadBlockedTimeImpl invocation"); + IDATA UNUSED status = jthread_get_thread_blocked_time(thread, &nanos); + assert(status == TM_ERROR_NONE); + return nanos; +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadBlockedCountImpl(Ljava/lang/Thread;)J + */ +JNIEXPORT jlong JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadBlockedCountImpl(JNIEnv *, jobject, + jobject thread) +{ + TRACE2("management","getThreadBlockedCountImpl invocation"); + return jthread_get_thread_blocked_times_count(thread); +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.createThreadInfoImpl(JLjava/lang/String;Ljava/lang/Thread$State;ZZJJJJLjava/lang/String;JLjava/lang/String;[Ljava/lang/StackTraceElement;)Ljava/lang/management/ThreadInfo; + */ +JNIEXPORT jobject JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_createThreadInfoImpl( + JNIEnv *jenv_ext, + jobject , + jlong threadIdVal, + jstring threadNameVal, + jobject threadStateVal, + jboolean suspendedVal, + jboolean inNativeVal, + jlong blockedCountVal, + jlong blockedTimeVal, + jlong waitedCountVal, + jlong waitedTimeVal, + jstring lockNameVal, + jlong lockOwnerIdVal, + jstring lockOwnerNameVal, + jobjectArray stackTraceVal) +{ + 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, "", + "(JLjava/lang/String;Ljava/lang/Thread$State;ZZJJJJLjava/lang/String;" + "JLjava/lang/String;[Ljava/lang/StackTraceElement;)V"); + if (jenv->ExceptionCheck()) return NULL; + + jobject threadInfo = jenv->NewObject( + threadInfoClazz, + threadInfoClazzConstructor, + threadIdVal, + threadNameVal, + threadStateVal, + suspendedVal, + inNativeVal, + blockedCountVal, + blockedTimeVal, + waitedCountVal, + waitedTimeVal, + lockNameVal, + lockOwnerIdVal, + lockOwnerNameVal, + stackTraceVal); + + assert(!exn_raised()); + + return threadInfo; +/* + jmethodID id; + jclass clazz; + jobject newObj; + + clazz = jenv->FindClass("java/lang/management/ThreadInfo"); + id = jenv->GetMethodID(clazz, "", "(JLjava/lang/String;Ljava/lang/Thread$State;ZZJJJJLjava/lang/String;JLjava/lang/String;[Ljava/lang/StackTraceElement;)V"); + newObj = jenv->NewObject(clazz, id, threadIdVal, threadNameVal, threadStateVal, + suspendedVal, inNativeVal, blockedCountVal, + blockedTimeVal, waitedCountVal, waitedTimeVal, lockNameVal, + lockOwnerIdVal, lockOwnerNameVal, stackTraceVal); + return newObj; +*/ +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getThreadUserTimeImpl(J)J + */ +JNIEXPORT jlong JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getThreadUserTimeImpl(JNIEnv *, jobject, + jlong threadId) +{ + jlong nanos; + TRACE2("management","getThreadUserTimeImpl invocation"); + jthread thread = jthread_get_thread(threadId); + if (! thread){ + return -1; + } + IDATA UNUSED status = jthread_get_thread_user_cpu_time(thread, &nanos); + assert(status == TM_ERROR_NONE); + return nanos; +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.getTotalStartedThreadCountImpl()J + */ +JNIEXPORT jlong JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_getTotalStartedThreadCountImpl(JNIEnv *, jobject) +{ + jint count; + TRACE2("management","getTotalStartedThreadCountImpl invocation"); + IDATA UNUSED status = jthread_get_total_started_thread_count(&count); + assert(status == TM_ERROR_NONE); + return count; +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.isCurrentThreadCpuTimeSupportedImpl()Z + */ +JNIEXPORT jboolean JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isCurrentThreadCpuTimeSupportedImpl(JNIEnv *, jobject) +{ + TRACE2("management","isCurrentThreadCpuTimeSupportedImpl invocation"); + return jthread_is_current_thread_cpu_time_supported(); +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.isThreadContentionMonitoringEnabledImpl()Z + */ +JNIEXPORT jboolean JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isThreadContentionMonitoringEnabledImpl(JNIEnv *, jobject) +{ + TRACE2("management","isThreadContentionMonitoringEnabledImpl invocation"); + return jthread_is_thread_contention_monitoring_enabled(); +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.isThreadContentionMonitoringSupportedImpl()Z + */ +JNIEXPORT jboolean JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isThreadContentionMonitoringSupportedImpl(JNIEnv *, jobject) +{ + TRACE2("management","isThreadContentionMonitoringSupportedImpl invocation"); + return jthread_is_thread_contention_monitoring_supported(); +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.isThreadCpuTimeEnabledImpl()Z + */ +JNIEXPORT jboolean JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isThreadCpuTimeEnabledImpl(JNIEnv *, jobject) +{ + TRACE2("management","isThreadCpuTimeEnabledImpl invocation"); + return jthread_is_thread_cpu_time_enabled(); +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.isThreadCpuTimeSupportedImpl()Z + */ +JNIEXPORT jboolean JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_isThreadCpuTimeSupportedImpl(JNIEnv *, jobject) +{ + TRACE2("management","isThreadCpuTimeSupportedImpl invocation"); + return jthread_is_thread_cpu_time_supported(); +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.resetPeakThreadCountImpl()V + */ +JNIEXPORT void JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_resetPeakThreadCountImpl(JNIEnv *, jobject) +{ + TRACE2("management","resetPeakThreadCountImpl invocation"); + IDATA UNUSED status = jthread_reset_peak_thread_count(); + assert(status == TM_ERROR_NONE); +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.setThreadContentionMonitoringEnabledImpl(Z)V + */ +JNIEXPORT void JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_setThreadContentionMonitoringEnabledImpl( + JNIEnv *, + jobject, + jboolean new_value) +{ + // TODO implement this method stub correctly + TRACE2("management","setThreadContentionMonitoringEnabledImpl invocation"); + jthread_set_thread_contention_monitoring_enabled(new_value); +}; + +/* + * Method: org.apache.harmony.lang.management.ThreadMXBeanImpl.setThreadCpuTimeEnabledImpl(Z)V + */ +JNIEXPORT void JNICALL +Java_org_apache_harmony_lang_management_ThreadMXBeanImpl_setThreadCpuTimeEnabledImpl(JNIEnv *, jobject, + jboolean 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 462806) +++ vm/thread/src/thread_ti_instr.c (working copy) @@ -228,6 +228,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_java_attrs.c =================================================================== --- vm/thread/src/thread_java_attrs.c (revision 462806) +++ vm/thread/src/thread_java_attrs.c (working copy) @@ -30,6 +30,25 @@ #include "thread_private.h" /** + * Returns the id for the thread. + * + * @param[in] java_thread thread + * @return id for this thread + * @sa java.lang.Thread.getId() + */ +jlong VMCALL jthread_get_thread_id(jthread thread){ + // FIXME: there are two different ids for one thread now - one returned by + // java.lang.Thread.getId() and the other returned by hythread_get_id(native thread). + // They have to be the same. + // This method returns the same id as java.lang.Thread.getId() + JNIEnv * jni_env = jthread_get_JNI_env(thread); + jclass cl =(* jni_env)->FindClass(jni_env, "java/lang/Thread"); + jmethodID id = (* jni_env)->GetMethodID(jni_env, cl, "getName","()Ljava/lang/String;"); + id = (* jni_env)->GetMethodID(jni_env, cl, "getId","()J"); + return (* jni_env)->CallLongMethod (jni_env, thread, id); +} + +/** * Returns the priority for the thread. * * @param[in] java_thread thread those attribute is read Index: vm/thread/src/thread_private.h =================================================================== --- vm/thread/src/thread_private.h (revision 462806) +++ vm/thread/src/thread_private.h (working copy) @@ -348,11 +348,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; @@ -560,6 +570,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 @@ -634,6 +645,10 @@ void *array_delete(array_t array, UDATA index); void *array_get(array_t array, UDATA index); +/** + * Auxiliary function to update peak count + */ +void update_peak_count(); #ifdef __cplusplus Index: vm/thread/src/thread_java_basic.c =================================================================== --- vm/thread/src/thread_java_basic.c (revision 462806) +++ vm/thread/src/thread_java_basic.c (working copy) @@ -170,6 +170,8 @@ attrs->priority, 0, wrapper_proc, data); TRACE(("TM: Created thread: id=%d", tm_native_thread->thread_id)); + total_started_thread_count++; + update_peak_count(); return status; } @@ -327,6 +329,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; @@ -547,7 +553,34 @@ * @return jthread for the given ID, or NULL if there are no such. */ jthread jthread_get_thread(jlong thread_id) { + // FIXME: there are two different ids for one thread now - one returned by + // java.lang.Thread.getId() and the other returned by hythread_get_id(native thread). + // They have to be the same and iterator have to be excluded here. + // The parameter of the method is the same id as java.lang.Thread.getId() + hythread_iterator_t iterator; + hythread_group_t java_thread_group = get_java_thread_group(); + hythread_t tm_native_thread; + jvmti_thread_t tm_java_thread; + jthread java_thread; + jthread res = NULL; + jlong id; + iterator = hythread_iterator_create(java_thread_group); + while (hythread_iterator_has_next(iterator)){ + tm_native_thread = hythread_iterator_next(&iterator); + tm_java_thread = hythread_get_private_data(tm_native_thread); + if (tm_java_thread){ + java_thread = tm_java_thread->thread_object; + id = jthread_get_thread_id(java_thread); + if (id == thread_id){ + res = (*(tm_java_thread->jenv))->NewGlobalRef(tm_java_thread->jenv, java_thread); + break; + } + } + } + hythread_iterator_release(&iterator); + return res; +/* hythread_t tm_native_thread; jvmti_thread_t tm_java_thread; jthread java_thread; @@ -560,6 +593,7 @@ java_thread = tm_java_thread->thread_object; assert(java_thread); return java_thread; +*/ } /** Index: vm/thread/src/thread_ti_timing.c =================================================================== --- vm/thread/src/thread_ti_timing.c (revision 462806) +++ vm/thread/src/thread_ti_timing.c (working copy) @@ -31,6 +31,17 @@ #include "thread_private.h" #include "apr_thread_ext.h" +#ifdef PLATFORM_POSIX +#define THREAD_CPU_TIME_SUPPORTED 0 +#else +#define THREAD_CPU_TIME_SUPPORTED 1 +#endif + +/* + * Thread CPU time enabled flag. + */ +int thread_cpu_time_enabled = 0; + /** * Returns time spent by the specific thread while contending for monitors. * @@ -116,3 +127,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 462806) +++ vm/thread/src/thread_ti_others.c (working copy) @@ -30,14 +30,30 @@ #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; + +/* * Peak count */ +int peak_thread_count = 0; /** * Resets the thread peak counter. */ IDATA jthread_reset_peak_thread_count () { + + peak_thread_count = 0; + update_peak_count(); return TM_ERROR_NONE; } @@ -45,10 +61,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 @@ -64,3 +111,30 @@ return &tm_java_thread->jvmti_local_storage; } + +void update_peak_count(){ + // FIXME: exclude iterator and use global alive_java_thread_count + hythread_iterator_t iterator; + hythread_group_t java_thread_group = get_java_thread_group(); + hythread_t tm_native_thread; + jvmti_thread_t tm_java_thread; + int java_thread_count = 0; + + assert(java_thread_group); + iterator = hythread_iterator_create(java_thread_group); + while (hythread_iterator_has_next(iterator)){ + tm_native_thread = hythread_iterator_next(&iterator); + tm_java_thread = hythread_get_private_data(tm_native_thread); + if (tm_java_thread){ + java_thread_count++; + } + } + hythread_iterator_release(&iterator); + if (java_thread_count > total_started_thread_count){ + total_started_thread_count = java_thread_count; + } + if (java_thread_count > peak_thread_count){ + peak_thread_count = java_thread_count; + } +} +