8191789: migrate more Thread-SMR stuff from thread.[ch]pp -> threadSMR.[ch]pp

Reviewed-by: stefank, coleenp, dholmes, gthornbr
This commit is contained in:
Daniel D. Daugherty 2017-12-06 15:19:30 -05:00
parent 318c0d74ab
commit 230b5768d7
9 changed files with 1114 additions and 1069 deletions

View file

@ -357,7 +357,7 @@ void print_statistics() {
MemTracker::final_report(tty); MemTracker::final_report(tty);
} }
Threads::log_smr_statistics(); ThreadsSMRSupport::log_smr_statistics();
} }
#else // PRODUCT MODE STATISTICS #else // PRODUCT MODE STATISTICS
@ -399,7 +399,7 @@ void print_statistics() {
Method::print_touched_methods(tty); Method::print_touched_methods(tty);
} }
Threads::log_smr_statistics(); ThreadsSMRSupport::log_smr_statistics();
} }
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -58,6 +58,7 @@
class ThreadSafepointState; class ThreadSafepointState;
class ThreadsList; class ThreadsList;
class ThreadsSMRSupport;
class NestedThreadsList; class NestedThreadsList;
class JvmtiThreadState; class JvmtiThreadState;
@ -103,7 +104,6 @@ class WorkerThread;
// - WatcherThread // - WatcherThread
class Thread: public ThreadShadow { class Thread: public ThreadShadow {
friend class Threads;
friend class VMStructs; friend class VMStructs;
friend class JVMCIVMStructs; friend class JVMCIVMStructs;
private: private:
@ -121,12 +121,14 @@ class Thread: public ThreadShadow {
protected: protected:
// Support for forcing alignment of thread objects for biased locking // Support for forcing alignment of thread objects for biased locking
void* _real_malloc_address; void* _real_malloc_address;
// JavaThread lifecycle support: // JavaThread lifecycle support:
friend class ScanHazardPtrGatherProtectedThreadsClosure; friend class ScanHazardPtrGatherProtectedThreadsClosure; // for cmpxchg_threads_hazard_ptr(), get_threads_hazard_ptr(), is_hazard_ptr_tagged() access
friend class ScanHazardPtrGatherThreadsListClosure; friend class ScanHazardPtrGatherThreadsListClosure; // for get_nested_threads_hazard_ptr(), get_threads_hazard_ptr(), untag_hazard_ptr() access
friend class ScanHazardPtrPrintMatchingThreadsClosure; friend class ScanHazardPtrPrintMatchingThreadsClosure; // for get_threads_hazard_ptr(), is_hazard_ptr_tagged() access
friend class ThreadsListHandle; friend class ThreadsListSetter; // for get_threads_hazard_ptr() access
friend class ThreadsListSetter; friend class ThreadsSMRSupport; // for get_threads_hazard_ptr() access
ThreadsList* volatile _threads_hazard_ptr; ThreadsList* volatile _threads_hazard_ptr;
ThreadsList* cmpxchg_threads_hazard_ptr(ThreadsList* exchange_value, ThreadsList* compare_value); ThreadsList* cmpxchg_threads_hazard_ptr(ThreadsList* exchange_value, ThreadsList* compare_value);
ThreadsList* get_threads_hazard_ptr(); ThreadsList* get_threads_hazard_ptr();
@ -2126,62 +2128,18 @@ inline CompilerThread* CompilerThread::current() {
class Threads: AllStatic { class Threads: AllStatic {
friend class VMStructs; friend class VMStructs;
private: private:
// Safe Memory Reclamation (SMR) support: static JavaThread* _thread_list;
// The coordination between Threads::release_stable_list() and static int _number_of_threads;
// Threads::smr_delete() uses the smr_delete_lock in order to static int _number_of_non_daemon_threads;
// reduce the traffic on the Threads_lock. static int _return_code;
static Monitor* _smr_delete_lock; static int _thread_claim_parity;
// The '_cnt', '_max' and '_times" fields are enabled via
// -XX:+EnableThreadSMRStatistics (see thread.cpp for a
// description about each field):
static uint _smr_delete_lock_wait_cnt;
static uint _smr_delete_lock_wait_max;
// The smr_delete_notify flag is used for proper double-check
// locking in order to reduce the traffic on the smr_delete_lock.
static volatile uint _smr_delete_notify;
static volatile uint _smr_deleted_thread_cnt;
static volatile uint _smr_deleted_thread_time_max;
static volatile uint _smr_deleted_thread_times;
static ThreadsList* volatile _smr_java_thread_list;
static uint64_t _smr_java_thread_list_alloc_cnt;
static uint64_t _smr_java_thread_list_free_cnt;
static uint _smr_java_thread_list_max;
static uint _smr_nested_thread_list_max;
static volatile uint _smr_tlh_cnt;
static volatile uint _smr_tlh_time_max;
static volatile uint _smr_tlh_times;
static ThreadsList* _smr_to_delete_list;
static uint _smr_to_delete_list_cnt;
static uint _smr_to_delete_list_max;
static JavaThread* _thread_list;
static int _number_of_threads;
static int _number_of_non_daemon_threads;
static int _return_code;
static int _thread_claim_parity;
#ifdef ASSERT #ifdef ASSERT
static bool _vm_complete; static bool _vm_complete;
#endif #endif
static void initialize_java_lang_classes(JavaThread* main_thread, TRAPS); static void initialize_java_lang_classes(JavaThread* main_thread, TRAPS);
static void initialize_jsr292_core_classes(TRAPS); static void initialize_jsr292_core_classes(TRAPS);
static ThreadsList *acquire_stable_list_fast_path(Thread *self);
static ThreadsList *acquire_stable_list_nested_path(Thread *self);
static void add_smr_deleted_thread_times(uint add_value);
static void clear_smr_delete_notify();
static ThreadsList* get_smr_java_thread_list();
static void inc_smr_deleted_thread_cnt();
static void release_stable_list_fast_path(Thread *self);
static void release_stable_list_nested_path(Thread *self);
static void release_stable_list_wake_up(char *log_str);
static void set_smr_delete_notify();
static Monitor* smr_delete_lock() { return _smr_delete_lock; }
static bool smr_delete_notify();
static void smr_free_list(ThreadsList* threads);
static void update_smr_deleted_thread_time_max(uint new_value);
static ThreadsList* xchg_smr_java_thread_list(ThreadsList* new_list);
public: public:
// Thread management // Thread management
// force_daemon is a concession to JNI, where we may need to add a // force_daemon is a concession to JNI, where we may need to add a
@ -2191,19 +2149,6 @@ class Threads: AllStatic {
static void threads_do(ThreadClosure* tc); static void threads_do(ThreadClosure* tc);
static void possibly_parallel_threads_do(bool is_par, ThreadClosure* tc); static void possibly_parallel_threads_do(bool is_par, ThreadClosure* tc);
// SMR support:
static ThreadsList *acquire_stable_list(Thread *self, bool is_ThreadsListSetter);
static void release_stable_list(Thread *self);
static bool is_a_protected_JavaThread(JavaThread *thread);
static bool is_a_protected_JavaThread_with_lock(JavaThread *thread) {
MutexLockerEx ml(Threads_lock->owned_by_self() ? NULL : Threads_lock);
return is_a_protected_JavaThread(thread);
}
static void smr_delete(JavaThread *thread);
static void inc_smr_tlh_cnt();
static void update_smr_tlh_time_max(uint new_value);
static void add_smr_tlh_times(uint add_value);
// Initializes the vm and creates the vm thread // Initializes the vm and creates the vm thread
static jint create_vm(JavaVMInitArgs* args, bool* canTryAgain); static jint create_vm(JavaVMInitArgs* args, bool* canTryAgain);
static void convert_vm_init_libraries_to_agents(); static void convert_vm_init_libraries_to_agents();
@ -2264,10 +2209,7 @@ class Threads: AllStatic {
// Verification // Verification
static void verify(); static void verify();
static void log_smr_statistics();
static void print_on(outputStream* st, bool print_stacks, bool internal_format, bool print_concurrent_locks); static void print_on(outputStream* st, bool print_stacks, bool internal_format, bool print_concurrent_locks);
static void print_smr_info_on(outputStream* st);
static void print_smr_info_elements_on(outputStream* st, ThreadsList* t_list);
static void print(bool print_stacks, bool internal_format) { static void print(bool print_stacks, bool internal_format) {
// this function is only used by debug.cpp // this function is only used by debug.cpp
print_on(tty, print_stacks, internal_format, false /* no concurrent lock printed */); print_on(tty, print_stacks, internal_format, false /* no concurrent lock printed */);

View file

@ -28,7 +28,6 @@
#include "runtime/atomic.hpp" #include "runtime/atomic.hpp"
#include "runtime/os.inline.hpp" #include "runtime/os.inline.hpp"
#include "runtime/thread.hpp" #include "runtime/thread.hpp"
#include "runtime/threadSMR.hpp"
inline void Thread::set_suspend_flag(SuspendFlags f) { inline void Thread::set_suspend_flag(SuspendFlags f) {
assert(sizeof(jint) == sizeof(_suspend_flags), "size mismatch"); assert(sizeof(jint) == sizeof(_suspend_flags), "size mismatch");
@ -212,26 +211,4 @@ inline void JavaThread::set_terminated_value() {
OrderAccess::release_store((volatile jint *) &_terminated, (jint) _thread_terminated); OrderAccess::release_store((volatile jint *) &_terminated, (jint) _thread_terminated);
} }
inline void Threads::add_smr_tlh_times(uint add_value) {
Atomic::add(add_value, &_smr_tlh_times);
}
inline void Threads::inc_smr_tlh_cnt() {
Atomic::inc(&_smr_tlh_cnt);
}
inline void Threads::update_smr_tlh_time_max(uint new_value) {
while (true) {
uint cur_value = _smr_tlh_time_max;
if (new_value <= cur_value) {
// No need to update max value so we're done.
break;
}
if (Atomic::cmpxchg(new_value, &_smr_tlh_time_max, cur_value) == cur_value) {
// Updated max value so we're done. Otherwise try it all again.
break;
}
}
}
#endif // SHARE_VM_RUNTIME_THREAD_INLINE_HPP #endif // SHARE_VM_RUNTIME_THREAD_INLINE_HPP

File diff suppressed because it is too large Load diff

View file

@ -77,11 +77,77 @@
// longer protected by a ThreadsListHandle. // longer protected by a ThreadsListHandle.
// SMR Support for the Threads class.
//
class ThreadsSMRSupport : AllStatic {
// The coordination between ThreadsSMRSupport::release_stable_list() and
// ThreadsSMRSupport::smr_delete() uses the smr_delete_lock in order to
// reduce the traffic on the Threads_lock.
static Monitor* _smr_delete_lock;
// The '_cnt', '_max' and '_times" fields are enabled via
// -XX:+EnableThreadSMRStatistics (see thread.cpp for a
// description about each field):
static uint _smr_delete_lock_wait_cnt;
static uint _smr_delete_lock_wait_max;
// The smr_delete_notify flag is used for proper double-check
// locking in order to reduce the traffic on the smr_delete_lock.
static volatile uint _smr_delete_notify;
static volatile uint _smr_deleted_thread_cnt;
static volatile uint _smr_deleted_thread_time_max;
static volatile uint _smr_deleted_thread_times;
static ThreadsList* volatile _smr_java_thread_list;
static uint64_t _smr_java_thread_list_alloc_cnt;
static uint64_t _smr_java_thread_list_free_cnt;
static uint _smr_java_thread_list_max;
static uint _smr_nested_thread_list_max;
static volatile uint _smr_tlh_cnt;
static volatile uint _smr_tlh_time_max;
static volatile uint _smr_tlh_times;
static ThreadsList* _smr_to_delete_list;
static uint _smr_to_delete_list_cnt;
static uint _smr_to_delete_list_max;
static ThreadsList *acquire_stable_list_fast_path(Thread *self);
static ThreadsList *acquire_stable_list_nested_path(Thread *self);
static void add_smr_deleted_thread_times(uint add_value);
static void add_smr_tlh_times(uint add_value);
static void clear_smr_delete_notify();
static void inc_smr_deleted_thread_cnt();
static void inc_smr_java_thread_list_alloc_cnt();
static void inc_smr_tlh_cnt();
static bool is_a_protected_JavaThread(JavaThread *thread);
static void release_stable_list_fast_path(Thread *self);
static void release_stable_list_nested_path(Thread *self);
static void release_stable_list_wake_up(char *log_str);
static void set_smr_delete_notify();
static Monitor* smr_delete_lock() { return _smr_delete_lock; }
static bool smr_delete_notify();
static void smr_free_list(ThreadsList* threads);
static void update_smr_deleted_thread_time_max(uint new_value);
static void update_smr_java_thread_list_max(uint new_value);
static void update_smr_tlh_time_max(uint new_value);
static ThreadsList* xchg_smr_java_thread_list(ThreadsList* new_list);
public:
static ThreadsList *acquire_stable_list(Thread *self, bool is_ThreadsListSetter);
static void add_thread(JavaThread *thread);
static ThreadsList* get_smr_java_thread_list();
static bool is_a_protected_JavaThread_with_lock(JavaThread *thread);
static void release_stable_list(Thread *self);
static void remove_thread(JavaThread *thread);
static void smr_delete(JavaThread *thread);
static void update_smr_tlh_stats(uint millis);
// Logging and printing support:
static void log_smr_statistics();
static void print_smr_info_elements_on(outputStream* st, ThreadsList* t_list);
static void print_smr_info_on(outputStream* st);
};
// A fast list of JavaThreads. // A fast list of JavaThreads.
// //
class ThreadsList : public CHeapObj<mtThread> { class ThreadsList : public CHeapObj<mtThread> {
friend class ScanHazardPtrGatherProtectedThreadsClosure; friend class ThreadsSMRSupport; // for next_list(), set_next_list() access
friend class Threads;
const uint _length; const uint _length;
ThreadsList* _next_list; ThreadsList* _next_list;
@ -93,6 +159,9 @@ class ThreadsList : public CHeapObj<mtThread> {
ThreadsList *next_list() const { return _next_list; } ThreadsList *next_list() const { return _next_list; }
void set_next_list(ThreadsList *list) { _next_list = list; } void set_next_list(ThreadsList *list) { _next_list = list; }
static ThreadsList* add_thread(ThreadsList* list, JavaThread* java_thread);
static ThreadsList* remove_thread(ThreadsList* list, JavaThread* java_thread);
public: public:
ThreadsList(int entries); ThreadsList(int entries);
~ThreadsList(); ~ThreadsList();
@ -110,9 +179,6 @@ public:
int find_index_of_JavaThread(JavaThread* target); int find_index_of_JavaThread(JavaThread* target);
JavaThread* find_JavaThread_from_java_tid(jlong java_tid) const; JavaThread* find_JavaThread_from_java_tid(jlong java_tid) const;
bool includes(const JavaThread * const p) const; bool includes(const JavaThread * const p) const;
static ThreadsList* add_thread(ThreadsList* list, JavaThread* java_thread);
static ThreadsList* remove_thread(ThreadsList* list, JavaThread* java_thread);
}; };
// Linked list of ThreadsLists to support nested ThreadsListHandles. // Linked list of ThreadsLists to support nested ThreadsListHandles.

View file

@ -52,6 +52,32 @@ inline void ThreadsList::threads_do(T *cl) const {
} }
} }
// These three inlines are private to ThreadsSMRSupport, but
// they are called by public inline update_smr_tlh_stats() below:
inline void ThreadsSMRSupport::add_smr_tlh_times(uint add_value) {
Atomic::add(add_value, &_smr_tlh_times);
}
inline void ThreadsSMRSupport::inc_smr_tlh_cnt() {
Atomic::inc(&_smr_tlh_cnt);
}
inline void ThreadsSMRSupport::update_smr_tlh_time_max(uint new_value) {
while (true) {
uint cur_value = _smr_tlh_time_max;
if (new_value <= cur_value) {
// No need to update max value so we're done.
break;
}
if (Atomic::cmpxchg(new_value, &_smr_tlh_time_max, cur_value) == cur_value) {
// Updated max value so we're done. Otherwise try it all again.
break;
}
}
}
inline ThreadsList* ThreadsListSetter::list() { inline ThreadsList* ThreadsListSetter::list() {
ThreadsList *ret = _target->get_threads_hazard_ptr(); ThreadsList *ret = _target->get_threads_hazard_ptr();
assert(ret != NULL, "hazard ptr should be set"); assert(ret != NULL, "hazard ptr should be set");
@ -59,4 +85,19 @@ inline ThreadsList* ThreadsListSetter::list() {
return ret; return ret;
} }
inline ThreadsList* ThreadsSMRSupport::get_smr_java_thread_list() {
return (ThreadsList*)OrderAccess::load_acquire(&_smr_java_thread_list);
}
inline bool ThreadsSMRSupport::is_a_protected_JavaThread_with_lock(JavaThread *thread) {
MutexLockerEx ml(Threads_lock->owned_by_self() ? NULL : Threads_lock);
return is_a_protected_JavaThread(thread);
}
inline void ThreadsSMRSupport::update_smr_tlh_stats(uint millis) {
ThreadsSMRSupport::inc_smr_tlh_cnt();
ThreadsSMRSupport::add_smr_tlh_times(millis);
ThreadsSMRSupport::update_smr_tlh_time_max(millis);
}
#endif // SHARE_VM_RUNTIME_THREADSMR_INLINE_HPP #endif // SHARE_VM_RUNTIME_THREADSMR_INLINE_HPP

View file

@ -29,6 +29,7 @@
#include "memory/allocation.hpp" #include "memory/allocation.hpp"
#include "oops/oop.hpp" #include "oops/oop.hpp"
#include "runtime/thread.hpp" #include "runtime/thread.hpp"
#include "runtime/threadSMR.hpp"
#include "code/codeCache.hpp" #include "code/codeCache.hpp"
// The following classes are used for operations // The following classes are used for operations

View file

@ -33,6 +33,7 @@
#include "runtime/objectMonitor.inline.hpp" #include "runtime/objectMonitor.inline.hpp"
#include "runtime/perfData.hpp" #include "runtime/perfData.hpp"
#include "runtime/thread.hpp" #include "runtime/thread.hpp"
#include "runtime/threadSMR.hpp"
#include "services/management.hpp" #include "services/management.hpp"
#include "services/serviceUtil.hpp" #include "services/serviceUtil.hpp"