< prev index next >

src/hotspot/share/runtime/threadSMR.cpp

Print this page
rev 52711 : 8185005: Improve performance of ThreadMXBean.getThreadInfo(long ids[], int maxDepth)
Reviewed-by: sspitsyn, dholmes, dcubed, rehn

@@ -24,13 +24,15 @@
 
 #include "precompiled.hpp"
 #include "logging/logStream.hpp"
 #include "memory/allocation.inline.hpp"
 #include "runtime/jniHandles.inline.hpp"
+#include "runtime/sharedRuntime.hpp"
 #include "runtime/thread.inline.hpp"
 #include "runtime/threadSMR.inline.hpp"
 #include "runtime/vmOperations.hpp"
+#include "services/threadIdTable.hpp"
 #include "services/threadService.hpp"
 #include "utilities/copy.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/ostream.hpp"
 #include "utilities/resourceHash.hpp"

@@ -122,11 +124,10 @@
 
 // Max # of parallel ThreadsLists on the to-delete list.
 // Impl note: See _to_delete_list_cnt note.
 uint                  ThreadsSMRSupport::_to_delete_list_max = 0;
 
-
 // 'inline' functions first so the definitions are before first use:
 
 inline void ThreadsSMRSupport::add_deleted_thread_times(uint add_value) {
   Atomic::add(add_value, &_deleted_thread_times);
 }

@@ -596,21 +597,33 @@
   }
   return -1;
 }
 
 JavaThread* ThreadsList::find_JavaThread_from_java_tid(jlong java_tid) const {
+  ThreadIdTable::lazy_initialize(this);
+  JavaThread* thread = ThreadIdTable::find_thread_by_tid(java_tid);
+  if (thread == NULL) {
+    // If the thread is not found in the table find it
+    // with a linear search and add to the table.
   for (uint i = 0; i < length(); i++) {
-    JavaThread* thread = thread_at(i);
+      thread = thread_at(i);
     oop tobj = thread->threadObj();
     // Ignore the thread if it hasn't run yet, has exited
     // or is starting to exit.
-    if (tobj != NULL && !thread->is_exiting() &&
-        java_tid == java_lang_Thread::thread_id(tobj)) {
-      // found a match
+      if (tobj != NULL && java_tid == java_lang_Thread::thread_id(tobj)) {
+        MutexLocker ml(Threads_lock);
+        // Must be inside the lock to ensure that we don't add a thread to the table
+        // that has just passed the removal point in ThreadsSMRSupport::remove_thread()
+        if (!thread->is_exiting()) {
+          ThreadIdTable::add_thread(java_tid, thread);
       return thread;
     }
   }
+    }
+  } else if (!thread->is_exiting()) {
+    return thread;
+  }
   return NULL;
 }
 
 void ThreadsList::inc_nested_handle_cnt() {
   // The increment needs to be MO_SEQ_CST. At the moment, the Atomic::inc

@@ -740,10 +753,14 @@
   // Initial _java_thread_list will not generate a "Threads::add" mesg.
   log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::add: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list));
 
   ThreadsList *old_list = xchg_java_thread_list(new_list);
   free_list(old_list);
+  if (ThreadIdTable::is_initialized()) {
+    jlong tid = SharedRuntime::get_java_tid(thread);
+    ThreadIdTable::add_thread(tid, thread);
+  }
 }
 
 // set_delete_notify() and clear_delete_notify() are called
 // under the protection of the delete_lock, but we also use an
 // Atomic operation to ensure the memory update is seen earlier than

@@ -900,10 +917,14 @@
     log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::release_stable_list notified %s", os::current_thread_id(), log_str);
   }
 }
 
 void ThreadsSMRSupport::remove_thread(JavaThread *thread) {
+  if (ThreadIdTable::is_initialized()) {
+    jlong tid = SharedRuntime::get_java_tid(thread);
+    ThreadIdTable::remove_thread(tid);
+  }
   ThreadsList *new_list = ThreadsList::remove_thread(ThreadsSMRSupport::get_java_thread_list(), thread);
   if (EnableThreadSMRStatistics) {
     ThreadsSMRSupport::inc_java_thread_list_alloc_cnt();
     // This list is smaller so no need to check for a "longest" update.
   }
< prev index next >