< prev index next >

src/hotspot/share/runtime/threadSMR.hpp

Print this page
rev 49939 : imported patch 8191798.eosterlund.open.patch.00
rev 49940 : imported patch 8191798.dcubed.open.cr0.00

*** 26,35 **** --- 26,39 ---- #define SHARE_VM_RUNTIME_THREADSMR_HPP #include "memory/allocation.hpp" #include "runtime/timer.hpp" + class JavaThread; + class Monitor; + class outputStream; + class Thread; class ThreadClosure; // Thread Safe Memory Reclamation (Thread-SMR) support. // // ThreadsListHandles are used to safely perform operations on one or more
*** 80,89 **** --- 84,95 ---- // SMR Support for the Threads class. // class ThreadsSMRSupport : AllStatic { + friend class SafeThreadsListPtr; // for _nested_thread_list_max, delete_notify(), release_stable_list_wake_up() access + // The coordination between ThreadsSMRSupport::release_stable_list() and // ThreadsSMRSupport::smr_delete() uses the delete_lock in order to // reduce the traffic on the Threads_lock. static Monitor* _delete_lock; // The '_cnt', '_max' and '_times" fields are enabled via
*** 120,172 **** static void free_list(ThreadsList* threads); static void inc_deleted_thread_cnt(); static void inc_java_thread_list_alloc_cnt(); static void inc_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_delete_notify(); static void threads_do(ThreadClosure *tc); static void threads_do(ThreadClosure *tc, ThreadsList *list); static void update_deleted_thread_time_max(uint new_value); static void update_java_thread_list_max(uint new_value); static void update_tlh_time_max(uint new_value); ! static void verify_hazard_pointer_scanned(Thread *self, ThreadsList *threads); static ThreadsList* xchg_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_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_tlh_stats(uint millis); // Logging and printing support: static void log_statistics(); static void print_info_elements_on(outputStream* st, ThreadsList* t_list); static void print_info_on(outputStream* st); }; // A fast list of JavaThreads. // class ThreadsList : public CHeapObj<mtThread> { ! friend class ThreadsSMRSupport; // for next_list(), set_next_list() access const uint _length; ThreadsList* _next_list; JavaThread *const *const _threads; template <class T> void threads_do_dispatch(T *cl, JavaThread *const thread) const; ThreadsList *next_list() const { return _next_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: ThreadsList(int entries); --- 126,180 ---- static void free_list(ThreadsList* threads); static void inc_deleted_thread_cnt(); static void inc_java_thread_list_alloc_cnt(); static void inc_tlh_cnt(); static bool is_a_protected_JavaThread(JavaThread *thread); ! static void release_stable_list_wake_up(bool is_nested); static void set_delete_notify(); static void threads_do(ThreadClosure *tc); static void threads_do(ThreadClosure *tc, ThreadsList *list); static void update_deleted_thread_time_max(uint new_value); static void update_java_thread_list_max(uint new_value); static void update_tlh_time_max(uint new_value); ! static void verify_hazard_ptr_scanned(Thread *self, ThreadsList *threads); static ThreadsList* xchg_java_thread_list(ThreadsList* new_list); public: static void add_thread(JavaThread *thread); static ThreadsList* get_java_thread_list(); static bool is_a_protected_JavaThread_with_lock(JavaThread *thread); static void remove_thread(JavaThread *thread); static void smr_delete(JavaThread *thread); static void update_tlh_stats(uint millis); // Logging and printing support: static void log_statistics(); static void print_info_elements_on(outputStream* st, ThreadsList* t_list); static void print_info_on(outputStream* st); + static void print_info_on(const Thread* thread, outputStream* st); }; // A fast list of JavaThreads. // class ThreadsList : public CHeapObj<mtThread> { ! friend class SafeThreadsListPtr; // for {dec,inc}_nested_handle_cnt() access ! friend class ThreadsSMRSupport; // for _nested_handle_cnt, {add,remove}_thread(), {,set_}next_list() access const uint _length; ThreadsList* _next_list; JavaThread *const *const _threads; + volatile intx _nested_handle_cnt; template <class T> void threads_do_dispatch(T *cl, JavaThread *const thread) const; ThreadsList *next_list() const { return _next_list; } void set_next_list(ThreadsList *list) { _next_list = list; } + void inc_nested_handle_cnt(); + void dec_nested_handle_cnt(); + static ThreadsList* add_thread(ThreadsList* list, JavaThread* java_thread); static ThreadsList* remove_thread(ThreadsList* list, JavaThread* java_thread); public: ThreadsList(int entries);
*** 185,257 **** int find_index_of_JavaThread(JavaThread* target); JavaThread* find_JavaThread_from_java_tid(jlong java_tid) const; bool includes(const JavaThread * const p) const; }; ! // Linked list of ThreadsLists to support nested ThreadsListHandles. ! class NestedThreadsList : public CHeapObj<mtThread> { ! ThreadsList*const _t_list; ! NestedThreadsList* _next; public: ! NestedThreadsList(ThreadsList* t_list) : _t_list(t_list) { ! assert(Threads_lock->owned_by_self(), ! "must own Threads_lock for saved t_list to be valid."); } ! ThreadsList* t_list() { return _t_list; } ! NestedThreadsList* next() { return _next; } ! void set_next(NestedThreadsList* value) { _next = value; } }; // A helper to optionally set the hazard ptr in ourself. This helper can // be used by ourself or by another thread. If the hazard ptr is set(), // then the destructor will release it. // class ThreadsListSetter : public StackObj { private: ! bool _target_needs_release; // needs release only when set() ! Thread * _target; public: ! ThreadsListSetter() : _target_needs_release(false), _target(Thread::current()) { ! } ! ~ThreadsListSetter(); ! ThreadsList* list(); ! void set(); ! bool target_needs_release() { return _target_needs_release; } }; // This stack allocated ThreadsListHandle keeps all JavaThreads in the // ThreadsList from being deleted until it is safe. // class ThreadsListHandle : public StackObj { ! ThreadsList * _list; ! Thread *const _self; elapsedTimer _timer; // Enabled via -XX:+EnableThreadSMRStatistics. public: ThreadsListHandle(Thread *self = Thread::current()); ~ThreadsListHandle(); ThreadsList *list() const { ! return _list; } template <class T> void threads_do(T *cl) const { ! return _list->threads_do(cl); } bool cv_internal_thread_to_JavaThread(jobject jthread, JavaThread ** jt_pp, oop * thread_oop_p); bool includes(JavaThread* p) { ! return _list->includes(p); } uint length() const { ! return _list->length(); } }; // This stack allocated JavaThreadIterator is used to walk the // specified ThreadsList using the following style: --- 193,301 ---- int find_index_of_JavaThread(JavaThread* target); JavaThread* find_JavaThread_from_java_tid(jlong java_tid) const; bool includes(const JavaThread * const p) const; }; ! // An abstract safe ptr to a ThreadsList comprising either a stable hazard ptr ! // for leaves, or a retained reference count for nested uses. The user of this ! // API does not need to know which mechanism is providing the safety. ! class SafeThreadsListPtr { ! friend class ThreadsListSetter; ! ! SafeThreadsListPtr* _previous; ! Thread* _thread; ! ThreadsList* _list; ! bool _has_ref_count; ! bool _needs_release; ! ! void acquire_stable_list(); ! void acquire_stable_list_fast_path(); ! void acquire_stable_list_nested_path(); ! ! void release_stable_list(); ! ! void verify_hazard_ptr_scanned(); public: ! // Constructor that attaches the list onto a thread. ! SafeThreadsListPtr(Thread *thread, bool acquire) : ! _previous(NULL), ! _thread(thread), ! _list(NULL), ! _has_ref_count(false), ! _needs_release(false) ! { ! if (acquire) { ! acquire_stable_list(); ! } ! } ! ! // Constructor that transfers ownership of the pointer. ! SafeThreadsListPtr(SafeThreadsListPtr& other) : ! _previous(other._previous), ! _thread(other._thread), ! _list(other._list), ! _has_ref_count(other._has_ref_count), ! _needs_release(other._needs_release) ! { ! other._needs_release = false; ! } ! ! ~SafeThreadsListPtr() { ! if (_needs_release) { ! release_stable_list(); ! } } ! ThreadsList* list() const { return _list; } ! SafeThreadsListPtr* previous() const { return _previous; } ! void print_on(outputStream* st); }; // A helper to optionally set the hazard ptr in ourself. This helper can // be used by ourself or by another thread. If the hazard ptr is set(), // then the destructor will release it. // class ThreadsListSetter : public StackObj { private: ! SafeThreadsListPtr _list_ptr; public: ! ThreadsListSetter() : _list_ptr(Thread::current(), /* acquire */ false) {} ! ThreadsList* list() { return _list_ptr.list(); } ! void set() { _list_ptr.acquire_stable_list(); } ! bool is_set() { return _list_ptr._needs_release; } }; // This stack allocated ThreadsListHandle keeps all JavaThreads in the // ThreadsList from being deleted until it is safe. // class ThreadsListHandle : public StackObj { ! SafeThreadsListPtr _list_ptr; elapsedTimer _timer; // Enabled via -XX:+EnableThreadSMRStatistics. public: ThreadsListHandle(Thread *self = Thread::current()); ~ThreadsListHandle(); ThreadsList *list() const { ! return _list_ptr.list(); } template <class T> void threads_do(T *cl) const { ! return list()->threads_do(cl); } bool cv_internal_thread_to_JavaThread(jobject jthread, JavaThread ** jt_pp, oop * thread_oop_p); bool includes(JavaThread* p) { ! return list()->includes(p); } uint length() const { ! return list()->length(); } }; // This stack allocated JavaThreadIterator is used to walk the // specified ThreadsList using the following style:
< prev index next >