< prev index next >

src/hotspot/share/runtime/threadSMR.cpp

Print this page
rev 48162 : 8191789: migrate more Thread-SMR stuff from thread.[ch]pp -> threadSMR.[ch]pp
Reviewed-by: stefank
rev 48163 : CR round 0: dcubed - move more code into sort order, add update_smr_tlh_stats(); stefank - refactor Threads::add() and Threads::remove() to allow more ThreadsSMRSupport functions to be private, move is_a_protected_JavaThread_with_lock() to threadSMR.inline.hpp

@@ -128,10 +128,14 @@
 
 inline void ThreadsSMRSupport::inc_smr_deleted_thread_cnt() {
   Atomic::inc(&_smr_deleted_thread_cnt);
 }
 
+inline void ThreadsSMRSupport::inc_smr_java_thread_list_alloc_cnt() {
+  _smr_java_thread_list_alloc_cnt++;
+}
+
 inline void ThreadsSMRSupport::update_smr_deleted_thread_time_max(uint new_value) {
   while (true) {
     uint cur_value = _smr_deleted_thread_time_max;
     if (new_value <= cur_value) {
       // No need to update max value so we're done.

@@ -142,10 +146,20 @@
       break;
     }
   }
 }
 
+inline void ThreadsSMRSupport::update_smr_java_thread_list_max(uint new_value) {
+  if (new_value > _smr_java_thread_list_max) {
+    _smr_java_thread_list_max = new_value;
+  }
+}
+
+inline ThreadsList* ThreadsSMRSupport::xchg_smr_java_thread_list(ThreadsList* new_list) {
+  return (ThreadsList*)Atomic::xchg(new_list, &_smr_java_thread_list);
+}
+
 
 // Hash table of pointers found by a scan. Used for collecting hazard
 // pointers (ThreadsList references). Also used for collecting JavaThreads
 // that are indirectly referenced by hazard ptrs. An instance of this
 // class only contains one type of pointer.

@@ -368,34 +382,10 @@
 
 ThreadsList::~ThreadsList() {
   FREE_C_HEAP_ARRAY(JavaThread*, _threads);
 }
 
-// Remove a JavaThread from a ThreadsList. The returned ThreadsList is a
-// new copy of the specified ThreadsList with the specified JavaThread
-// removed.
-ThreadsList *ThreadsList::remove_thread(ThreadsList* list, JavaThread* java_thread) {
-  assert(list->_length > 0, "sanity");
-
-  uint i = (uint)list->find_index_of_JavaThread(java_thread);
-  assert(i < list->_length, "did not find JavaThread on the list");
-  const uint index = i;
-  const uint new_length = list->_length - 1;
-  const uint head_length = index;
-  const uint tail_length = (new_length >= index) ? (new_length - index) : 0;
-  ThreadsList *const new_list = new ThreadsList(new_length);
-
-  if (head_length > 0) {
-    Copy::disjoint_words((HeapWord*)list->_threads, (HeapWord*)new_list->_threads, head_length);
-  }
-  if (tail_length > 0) {
-    Copy::disjoint_words((HeapWord*)list->_threads + index + 1, (HeapWord*)new_list->_threads + index, tail_length);
-  }
-
-  return new_list;
-}
-
 // Add a JavaThread to a ThreadsList. The returned ThreadsList is a
 // new copy of the specified ThreadsList with the specified JavaThread
 // appended to the end.
 ThreadsList *ThreadsList::add_thread(ThreadsList *list, JavaThread *java_thread) {
   const uint index = list->_length;

@@ -448,21 +438,32 @@
     }
   }
   return false;
 }
 
-ThreadsListSetter::~ThreadsListSetter() {
-  if (_target_needs_release) {
-    // The hazard ptr in the target needs to be released.
-    ThreadsSMRSupport::release_stable_list(_target);
+// Remove a JavaThread from a ThreadsList. The returned ThreadsList is a
+// new copy of the specified ThreadsList with the specified JavaThread
+// removed.
+ThreadsList *ThreadsList::remove_thread(ThreadsList* list, JavaThread* java_thread) {
+  assert(list->_length > 0, "sanity");
+
+  uint i = (uint)list->find_index_of_JavaThread(java_thread);
+  assert(i < list->_length, "did not find JavaThread on the list");
+  const uint index = i;
+  const uint new_length = list->_length - 1;
+  const uint head_length = index;
+  const uint tail_length = (new_length >= index) ? (new_length - index) : 0;
+  ThreadsList *const new_list = new ThreadsList(new_length);
+
+  if (head_length > 0) {
+    Copy::disjoint_words((HeapWord*)list->_threads, (HeapWord*)new_list->_threads, head_length);
+  }
+  if (tail_length > 0) {
+    Copy::disjoint_words((HeapWord*)list->_threads + index + 1, (HeapWord*)new_list->_threads + index, tail_length);
   }
-}
 
-void ThreadsListSetter::set() {
-  assert(_target->get_threads_hazard_ptr() == NULL, "hazard ptr should not already be set");
-  (void) ThreadsSMRSupport::acquire_stable_list(_target, /* is_ThreadsListSetter */ true);
-  _target_needs_release = true;
+  return new_list;
 }
 
 ThreadsListHandle::ThreadsListHandle(Thread *self) : _list(ThreadsSMRSupport::acquire_stable_list(self, /* is_ThreadsListSetter */ false)), _self(self) {
   assert(self == Thread::current(), "sanity check");
   if (EnableThreadSMRStatistics) {

@@ -473,13 +474,11 @@
 ThreadsListHandle::~ThreadsListHandle() {
   ThreadsSMRSupport::release_stable_list(_self);
   if (EnableThreadSMRStatistics) {
     _timer.stop();
     uint millis = (uint)_timer.milliseconds();
-    ThreadsSMRSupport::inc_smr_tlh_cnt();
-    ThreadsSMRSupport::add_smr_tlh_times(millis);
-    ThreadsSMRSupport::update_smr_tlh_time_max(millis);
+    ThreadsSMRSupport::update_smr_tlh_stats(millis);
   }
 }
 
 // Convert an internal thread reference to a JavaThread found on the
 // associated ThreadsList. This ThreadsListHandle "protects" the

@@ -531,10 +530,23 @@
   // ThreadsListHandle in the caller.
   *jt_pp = java_thread;
   return true;
 }
 
+ThreadsListSetter::~ThreadsListSetter() {
+  if (_target_needs_release) {
+    // The hazard ptr in the target needs to be released.
+    ThreadsSMRSupport::release_stable_list(_target);
+  }
+}
+
+void ThreadsListSetter::set() {
+  assert(_target->get_threads_hazard_ptr() == NULL, "hazard ptr should not already be set");
+  (void) ThreadsSMRSupport::acquire_stable_list(_target, /* is_ThreadsListSetter */ true);
+  _target_needs_release = true;
+}
+
 // Acquire a stable ThreadsList.
 //
 ThreadsList *ThreadsSMRSupport::acquire_stable_list(Thread *self, bool is_ThreadsListSetter) {
   assert(self != NULL, "sanity check");
   // acquire_stable_list_nested_path() will grab the Threads_lock

@@ -637,10 +649,23 @@
   log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::acquire_stable_list: add NestedThreadsList node containing ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(node->t_list()));
 
   return node->t_list();
 }
 
+void ThreadsSMRSupport::add_thread(JavaThread *thread){
+  ThreadsList *new_list = ThreadsList::add_thread(ThreadsSMRSupport::get_smr_java_thread_list(), thread);
+  if (EnableThreadSMRStatistics) {
+    ThreadsSMRSupport::inc_smr_java_thread_list_alloc_cnt();
+    ThreadsSMRSupport::update_smr_java_thread_list_max(new_list->length());
+  }
+  // Initial _smr_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 = ThreadsSMRSupport::xchg_smr_java_thread_list(new_list);
+  ThreadsSMRSupport::smr_free_list(old_list);
+}
+
 // set_smr_delete_notify() and clear_smr_delete_notify() are called
 // under the protection of the smr_delete_lock, but we also use an
 // Atomic operation to ensure the memory update is seen earlier than
 // when the smr_delete_lock is dropped.
 //

@@ -776,10 +801,24 @@
     ml.notify_all();
     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) {
+  ThreadsList *new_list = ThreadsList::remove_thread(ThreadsSMRSupport::get_smr_java_thread_list(), thread);
+  if (EnableThreadSMRStatistics) {
+    ThreadsSMRSupport::inc_smr_java_thread_list_alloc_cnt();
+    // This list is smaller so no need to check for a "longest" update.
+  }
+
+  // Final _smr_java_thread_list will not generate a "Threads::remove" mesg.
+  log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::remove: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list));
+
+  ThreadsList *old_list = ThreadsSMRSupport::xchg_smr_java_thread_list(new_list);
+  ThreadsSMRSupport::smr_free_list(old_list);
+}
+
 // See note for clear_smr_delete_notify().
 //
 void ThreadsSMRSupport::set_smr_delete_notify() {
   Atomic::inc(&_smr_delete_notify);
 }

@@ -936,10 +975,13 @@
   }
 
   delete scan_table;
 }
 
+
+// Debug, logging, and printing stuff at the end:
+
 // Log Threads class SMR info.
 void ThreadsSMRSupport::log_smr_statistics() {
   LogTarget(Info, thread, smr) log;
   if (log.is_enabled()) {
     LogStream out(log);
< prev index next >