< 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,137 ****
--- 128,141 ----
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,151 ****
--- 146,165 ----
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,401 ****
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;
--- 382,391 ----
*** 448,468 ****
}
}
return false;
}
! 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;
}
ThreadsListHandle::ThreadsListHandle(Thread *self) : _list(ThreadsSMRSupport::acquire_stable_list(self, /* is_ThreadsListSetter */ false)), _self(self) {
assert(self == Thread::current(), "sanity check");
if (EnableThreadSMRStatistics) {
--- 438,469 ----
}
}
return false;
}
! // 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;
}
ThreadsListHandle::ThreadsListHandle(Thread *self) : _list(ThreadsSMRSupport::acquire_stable_list(self, /* is_ThreadsListSetter */ false)), _self(self) {
assert(self == Thread::current(), "sanity check");
if (EnableThreadSMRStatistics) {
*** 473,485 ****
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);
}
}
// Convert an internal thread reference to a JavaThread found on the
// associated ThreadsList. This ThreadsListHandle "protects" the
--- 474,484 ----
ThreadsListHandle::~ThreadsListHandle() {
ThreadsSMRSupport::release_stable_list(_self);
if (EnableThreadSMRStatistics) {
_timer.stop();
uint millis = (uint)_timer.milliseconds();
! ThreadsSMRSupport::update_smr_tlh_stats(millis);
}
}
// Convert an internal thread reference to a JavaThread found on the
// associated ThreadsList. This ThreadsListHandle "protects" the
*** 531,540 ****
--- 530,552 ----
// 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,646 ****
--- 649,671 ----
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,785 ****
--- 801,824 ----
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,945 ****
--- 975,987 ----
}
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 >