< 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 >