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