< prev index next >

src/hotspot/share/services/threadService.cpp

Print this page
rev 52112 : [mq]: 8021335

@@ -55,12 +55,10 @@
 
 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;
 

@@ -99,14 +97,20 @@
   // to synchronize with thread addition and removal.
   MutexLockerEx mu(Threads_lock);
   _peak_threads_count->set_value(get_live_thread_count());
 }
 
+static bool is_hidden_thread(JavaThread *thread) {
+  // hide VM internal or JVMTI agent threads
+  return thread->is_hidden_from_external_view() || thread->is_jvmti_agent_thread();
+}
+
 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()) {
+  assert(Threads_lock->owned_by_self(), "must have threads lock");
+
+  // Do not count hidden threads
+  if (is_hidden_thread(thread)) {
     return;
   }
 
   _total_threads_count->inc();
   _live_threads_count->inc();

@@ -118,35 +122,48 @@
   if (daemon) {
     _daemon_threads_count->inc();
   }
 }
 
-void ThreadService::remove_thread(JavaThread* thread, bool daemon) {
-  Atomic::dec(&_exiting_threads_count);
+void ThreadService::decrement_thread_counts(JavaThread* jt, bool daemon) {
+  assert(Threads_lock->owned_by_self(), "must have threads lock");
+
+  _live_threads_count->dec(1);
+
   if (daemon) {
-    Atomic::dec(&_exiting_daemon_threads_count);
+    _daemon_threads_count->dec(1);
   }
+}
+
+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()) {
+  // Do not count hidden threads
+  if (is_hidden_thread(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);
+  assert(!thread->is_terminated(), "must not be terminated");
+  if (!thread->is_exiting()) {
+    // JavaThread::exit() skipped calling current_thread_exiting()
+    decrement_thread_counts(thread, daemon);
   }
+
 }
 
-void ThreadService::current_thread_exiting(JavaThread* jt) {
-  assert(jt == JavaThread::current(), "Called by current thread");
-  Atomic::inc(&_exiting_threads_count);
+void ThreadService::current_thread_exiting(JavaThread* jt, bool daemon) {
+  assert(Threads_lock->owned_by_self(), "must have threads lock");
 
-  oop threadObj = jt->threadObj();
-  if (threadObj != NULL && java_lang_Thread::is_daemon(threadObj)) {
-    Atomic::inc(&_exiting_daemon_threads_count);
+  // Do not count hidden threads
+  if (is_hidden_thread(jt)) {
+    return;
   }
+
+  assert(jt == JavaThread::current(), "Called by current thread");
+  assert(!jt->is_terminated() && jt->is_exiting(), "must be exiting");
+
+  decrement_thread_counts(jt, daemon);
 }
 
 // FIXME: JVMTI should call this function
 Handle ThreadService::get_current_contended_monitor(JavaThread* thread) {
   assert(thread != NULL, "should be non-NULL");
< prev index next >