< prev index next >
src/hotspot/share/services/threadService.cpp
Print this page
rev 52112 : [mq]: 8021335
*** 55,66 ****
PerfCounter* ThreadService::_total_threads_count = NULL;
PerfVariable* ThreadService::_live_threads_count = NULL;
PerfVariable* ThreadService::_peak_threads_count = NULL;
PerfVariable* ThreadService::_daemon_threads_count = NULL;
! volatile int ThreadService::_exiting_threads_count = 0;
! volatile int ThreadService::_exiting_daemon_threads_count = 0;
ThreadDumpResult* ThreadService::_threaddump_list = NULL;
static const int INITIAL_ARRAY_SIZE = 10;
--- 55,66 ----
PerfCounter* ThreadService::_total_threads_count = NULL;
PerfVariable* ThreadService::_live_threads_count = NULL;
PerfVariable* ThreadService::_peak_threads_count = NULL;
PerfVariable* ThreadService::_daemon_threads_count = NULL;
! volatile int ThreadService::_atomic_threads_count = 0;
! volatile int ThreadService::_atomic_daemon_threads_count = 0;
ThreadDumpResult* ThreadService::_threaddump_list = NULL;
static const int INITIAL_ARRAY_SIZE = 10;
*** 100,152 ****
MutexLockerEx mu(Threads_lock);
_peak_threads_count->set_value(get_live_thread_count());
}
void ThreadService::add_thread(JavaThread* thread, bool daemon) {
// Do not count VM internal or JVMTI agent threads
if (thread->is_hidden_from_external_view() ||
thread->is_jvmti_agent_thread()) {
return;
}
_total_threads_count->inc();
_live_threads_count->inc();
! if (_live_threads_count->get_value() > _peak_threads_count->get_value()) {
! _peak_threads_count->set_value(_live_threads_count->get_value());
}
if (daemon) {
_daemon_threads_count->inc();
}
}
! void ThreadService::remove_thread(JavaThread* thread, bool daemon) {
! Atomic::dec(&_exiting_threads_count);
! if (daemon) {
! Atomic::dec(&_exiting_daemon_threads_count);
}
if (thread->is_hidden_from_external_view() ||
thread->is_jvmti_agent_thread()) {
return;
}
! _live_threads_count->set_value(_live_threads_count->get_value() - 1);
if (daemon) {
! _daemon_threads_count->set_value(_daemon_threads_count->get_value() - 1);
! }
}
void ThreadService::current_thread_exiting(JavaThread* jt) {
assert(jt == JavaThread::current(), "Called by current thread");
! Atomic::inc(&_exiting_threads_count);
! oop threadObj = jt->threadObj();
! if (threadObj != NULL && java_lang_Thread::is_daemon(threadObj)) {
! Atomic::inc(&_exiting_daemon_threads_count);
! }
}
// FIXME: JVMTI should call this function
Handle ThreadService::get_current_contended_monitor(JavaThread* thread) {
assert(thread != NULL, "should be non-NULL");
--- 100,201 ----
MutexLockerEx mu(Threads_lock);
_peak_threads_count->set_value(get_live_thread_count());
}
void ThreadService::add_thread(JavaThread* thread, bool daemon) {
+ assert(Threads_lock->owned_by_self(), "must have threads lock");
+
// Do not count VM internal or JVMTI agent threads
if (thread->is_hidden_from_external_view() ||
thread->is_jvmti_agent_thread()) {
return;
}
_total_threads_count->inc();
_live_threads_count->inc();
+ Atomic::inc(&_atomic_threads_count);
! if (_atomic_threads_count > _peak_threads_count->get_value()) {
! _peak_threads_count->set_value(_atomic_threads_count);
}
if (daemon) {
_daemon_threads_count->inc();
+ Atomic::inc(&_atomic_daemon_threads_count);
}
}
! void ThreadService::decrement_thread_counts(JavaThread* jt) {
! Atomic::dec(&_atomic_threads_count);
!
! oop threadObj = jt->threadObj();
! if (threadObj != NULL && java_lang_Thread::is_daemon(threadObj)) {
! Atomic::dec(&_atomic_daemon_threads_count);
}
+ }
+ void ThreadService::remove_thread(JavaThread* thread, bool daemon) {
+ assert(Threads_lock->owned_by_self(), "must have threads lock");
if (thread->is_hidden_from_external_view() ||
thread->is_jvmti_agent_thread()) {
return;
}
! assert(!thread->is_terminated(), "must not be terminated");
! if (!thread->is_exiting()) {
! // JavaThread::exit() skipped calling current_thread_exiting()
! decrement_thread_counts(thread);
! }
!
! int daemon_count = _atomic_daemon_threads_count;
! int count = _atomic_threads_count;
!
! // Counts are incremented at the same time, but atomic counts are
! // decremented earlier than perf counts.
! assert(_live_threads_count->get_value() > count,
! "thread count mismatch %d : %d",
! (int)_live_threads_count->get_value(), count);
!
! _live_threads_count->dec(1);
if (daemon) {
! assert(_daemon_threads_count->get_value() > daemon_count,
! "thread count mismatch %d : %d",
! (int)_daemon_threads_count->get_value(), daemon_count);
!
! _daemon_threads_count->dec(1);
! }
!
! // Counts are incremented at the same time, but atomic counts are
! // decremented earlier than perf counts.
! assert(_daemon_threads_count->get_value() >= daemon_count,
! "thread count mismatch %d : %d",
! (int)_daemon_threads_count->get_value(), daemon_count);
! assert(_live_threads_count->get_value() >= count,
! "thread count mismatch %d : %d",
! (int)_live_threads_count->get_value(), count);
! assert(_live_threads_count->get_value() > 0 ||
! (_live_threads_count->get_value() == 0 && count == 0 &&
! _daemon_threads_count->get_value() == 0 && daemon_count == 0),
! "thread counts should reach 0 at the same time, live %d,%d daemon %d,%d",
! (int)_live_threads_count->get_value(), count,
! (int)_daemon_threads_count->get_value(), daemon_count);
! assert(_daemon_threads_count->get_value() > 0 ||
! (_daemon_threads_count->get_value() == 0 && daemon_count == 0),
! "thread counts should reach 0 at the same time, daemon %d,%d",
! (int)_daemon_threads_count->get_value(), daemon_count);
}
void ThreadService::current_thread_exiting(JavaThread* jt) {
+ if (jt->is_hidden_from_external_view() ||
+ jt->is_jvmti_agent_thread()) {
+ return;
+ }
+
assert(jt == JavaThread::current(), "Called by current thread");
! assert(!jt->is_terminated() && jt->is_exiting(), "must be exiting");
! decrement_thread_counts(jt);
}
// FIXME: JVMTI should call this function
Handle ThreadService::get_current_contended_monitor(JavaThread* thread) {
assert(thread != NULL, "should be non-NULL");
< prev index next >