< 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


  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_RUNTIME_THREADSMR_HPP
  26 #define SHARE_VM_RUNTIME_THREADSMR_HPP
  27 
  28 #include "memory/allocation.hpp"
  29 #include "runtime/timer.hpp"
  30 




  31 class ThreadClosure;
  32 
  33 // Thread Safe Memory Reclamation (Thread-SMR) support.
  34 //
  35 // ThreadsListHandles are used to safely perform operations on one or more
  36 // threads without the risk of the thread or threads exiting during the
  37 // operation. It is no longer necessary to hold the Threads_lock to safely
  38 // perform an operation on a target thread.
  39 //
  40 // There are several different ways to refer to java.lang.Thread objects
  41 // so we have a few ways to get a protected JavaThread *:
  42 //
  43 // JNI jobject example:
  44 //   jobject jthread = ...;
  45 //   :
  46 //   ThreadsListHandle tlh;
  47 //   JavaThread* jt = NULL;
  48 //   bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &jt, NULL);
  49 //   if (is_alive) {
  50 //     :  // do stuff with 'jt'...


  65 //   oop thread_obj = ...;
  66 //   :
  67 //   JavaThread *jt = NULL;
  68 //   ThreadsListHandle tlh;
  69 //   jvmtiError err = JvmtiExport::cv_oop_to_JavaThread(tlh.list(), thread_obj, &jt);
  70 //   if (err != JVMTI_ERROR_NONE) {
  71 //     return err;
  72 //   }
  73 //   :  // do stuff with 'jt'...
  74 //
  75 // A JavaThread * that is included in the ThreadsList that is held by
  76 // a ThreadsListHandle is protected as long as the ThreadsListHandle
  77 // remains in scope. The target JavaThread * may have logically exited,
  78 // but that target JavaThread * will not be deleted until it is no
  79 // longer protected by a ThreadsListHandle.
  80 
  81 
  82 // SMR Support for the Threads class.
  83 //
  84 class ThreadsSMRSupport : AllStatic {


  85   // The coordination between ThreadsSMRSupport::release_stable_list() and
  86   // ThreadsSMRSupport::smr_delete() uses the delete_lock in order to
  87   // reduce the traffic on the Threads_lock.
  88   static Monitor*              _delete_lock;
  89   // The '_cnt', '_max' and '_times" fields are enabled via
  90   // -XX:+EnableThreadSMRStatistics (see thread.cpp for a
  91   // description about each field):
  92   static uint                  _delete_lock_wait_cnt;
  93   static uint                  _delete_lock_wait_max;
  94   // The delete_notify flag is used for proper double-check
  95   // locking in order to reduce the traffic on the system wide
  96   // Thread-SMR delete_lock.
  97   static volatile uint         _delete_notify;
  98   static volatile uint         _deleted_thread_cnt;
  99   static volatile uint         _deleted_thread_time_max;
 100   static volatile uint         _deleted_thread_times;
 101   static ThreadsList* volatile _java_thread_list;
 102   static uint64_t              _java_thread_list_alloc_cnt;
 103   static uint64_t              _java_thread_list_free_cnt;
 104   static uint                  _java_thread_list_max;
 105   static uint                  _nested_thread_list_max;
 106   static volatile uint         _tlh_cnt;
 107   static volatile uint         _tlh_time_max;
 108   static volatile uint         _tlh_times;
 109   static ThreadsList*          _to_delete_list;
 110   static uint                  _to_delete_list_cnt;
 111   static uint                  _to_delete_list_max;
 112 
 113   static ThreadsList *acquire_stable_list_fast_path(Thread *self);
 114   static ThreadsList *acquire_stable_list_nested_path(Thread *self);
 115   static void add_deleted_thread_times(uint add_value);
 116   static void add_tlh_times(uint add_value);
 117   static void clear_delete_notify();
 118   static Monitor* delete_lock() { return _delete_lock; }
 119   static bool delete_notify();
 120   static void free_list(ThreadsList* threads);
 121   static void inc_deleted_thread_cnt();
 122   static void inc_java_thread_list_alloc_cnt();
 123   static void inc_tlh_cnt();
 124   static bool is_a_protected_JavaThread(JavaThread *thread);
 125   static void release_stable_list_fast_path(Thread *self);
 126   static void release_stable_list_nested_path(Thread *self);
 127   static void release_stable_list_wake_up(char *log_str);
 128   static void set_delete_notify();
 129   static void threads_do(ThreadClosure *tc);
 130   static void threads_do(ThreadClosure *tc, ThreadsList *list);
 131   static void update_deleted_thread_time_max(uint new_value);
 132   static void update_java_thread_list_max(uint new_value);
 133   static void update_tlh_time_max(uint new_value);
 134   static void verify_hazard_pointer_scanned(Thread *self, ThreadsList *threads);
 135   static ThreadsList* xchg_java_thread_list(ThreadsList* new_list);
 136 
 137  public:
 138   static ThreadsList *acquire_stable_list(Thread *self, bool is_ThreadsListSetter);
 139   static void add_thread(JavaThread *thread);
 140   static ThreadsList* get_java_thread_list();
 141   static bool is_a_protected_JavaThread_with_lock(JavaThread *thread);
 142   static void release_stable_list(Thread *self);
 143   static void remove_thread(JavaThread *thread);
 144   static void smr_delete(JavaThread *thread);
 145   static void update_tlh_stats(uint millis);
 146 
 147   // Logging and printing support:
 148   static void log_statistics();
 149   static void print_info_elements_on(outputStream* st, ThreadsList* t_list);
 150   static void print_info_on(outputStream* st);

 151 };
 152 
 153 // A fast list of JavaThreads.
 154 //
 155 class ThreadsList : public CHeapObj<mtThread> {
 156   friend class ThreadsSMRSupport;  // for next_list(), set_next_list() access

 157 
 158   const uint _length;
 159   ThreadsList* _next_list;
 160   JavaThread *const *const _threads;

 161 
 162   template <class T>
 163   void threads_do_dispatch(T *cl, JavaThread *const thread) const;
 164 
 165   ThreadsList *next_list() const        { return _next_list; }
 166   void set_next_list(ThreadsList *list) { _next_list = list; }
 167 



 168   static ThreadsList* add_thread(ThreadsList* list, JavaThread* java_thread);
 169   static ThreadsList* remove_thread(ThreadsList* list, JavaThread* java_thread);
 170 
 171 public:
 172   ThreadsList(int entries);
 173   ~ThreadsList();
 174 
 175   template <class T>
 176   void threads_do(T *cl) const;
 177 
 178   uint length() const                       { return _length; }
 179 
 180   JavaThread *const thread_at(uint i) const { return _threads[i]; }
 181 
 182   JavaThread *const *threads() const        { return _threads; }
 183 
 184   // Returns -1 if target is not found.
 185   int find_index_of_JavaThread(JavaThread* target);
 186   JavaThread* find_JavaThread_from_java_tid(jlong java_tid) const;
 187   bool includes(const JavaThread * const p) const;
 188 };
 189 
 190 // Linked list of ThreadsLists to support nested ThreadsListHandles.
 191 class NestedThreadsList : public CHeapObj<mtThread> {
 192   ThreadsList*const _t_list;
 193   NestedThreadsList* _next;















 194 
 195 public:
 196   NestedThreadsList(ThreadsList* t_list) : _t_list(t_list) {
 197     assert(Threads_lock->owned_by_self(),
 198            "must own Threads_lock for saved t_list to be valid.");

























 199   }
 200 
 201   ThreadsList* t_list() { return _t_list; }
 202   NestedThreadsList* next() { return _next; }
 203   void set_next(NestedThreadsList* value) { _next = value; }
 204 };
 205 
 206 // A helper to optionally set the hazard ptr in ourself. This helper can
 207 // be used by ourself or by another thread. If the hazard ptr is set(),
 208 // then the destructor will release it.
 209 //
 210 class ThreadsListSetter : public StackObj {
 211 private:
 212   bool _target_needs_release;  // needs release only when set()
 213   Thread * _target;
 214 
 215 public:
 216   ThreadsListSetter() : _target_needs_release(false), _target(Thread::current()) {
 217   }
 218   ~ThreadsListSetter();
 219   ThreadsList* list();
 220   void set();
 221   bool target_needs_release() { return _target_needs_release; }
 222 };
 223 
 224 // This stack allocated ThreadsListHandle keeps all JavaThreads in the
 225 // ThreadsList from being deleted until it is safe.
 226 //
 227 class ThreadsListHandle : public StackObj {
 228   ThreadsList * _list;
 229   Thread *const _self;
 230   elapsedTimer _timer;  // Enabled via -XX:+EnableThreadSMRStatistics.
 231 
 232 public:
 233   ThreadsListHandle(Thread *self = Thread::current());
 234   ~ThreadsListHandle();
 235 
 236   ThreadsList *list() const {
 237     return _list;
 238   }
 239 
 240   template <class T>
 241   void threads_do(T *cl) const {
 242     return _list->threads_do(cl);
 243   }
 244 
 245   bool cv_internal_thread_to_JavaThread(jobject jthread, JavaThread ** jt_pp, oop * thread_oop_p);
 246 
 247   bool includes(JavaThread* p) {
 248     return _list->includes(p);
 249   }
 250 
 251   uint length() const {
 252     return _list->length();
 253   }
 254 };
 255 
 256 // This stack allocated JavaThreadIterator is used to walk the
 257 // specified ThreadsList using the following style:
 258 //
 259 //   JavaThreadIterator jti(t_list);
 260 //   for (JavaThread *jt = jti.first(); jt != NULL; jt = jti.next()) {
 261 //     ...
 262 //   }
 263 //
 264 class JavaThreadIterator : public StackObj {
 265   ThreadsList * _list;
 266   uint _index;
 267 
 268 public:
 269   JavaThreadIterator(ThreadsList *list) : _list(list), _index(0) {
 270     assert(list != NULL, "ThreadsList must not be NULL.");
 271   }
 272 




  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_RUNTIME_THREADSMR_HPP
  26 #define SHARE_VM_RUNTIME_THREADSMR_HPP
  27 
  28 #include "memory/allocation.hpp"
  29 #include "runtime/timer.hpp"
  30 
  31 class JavaThread;
  32 class Monitor;
  33 class outputStream;
  34 class Thread;
  35 class ThreadClosure;
  36 
  37 // Thread Safe Memory Reclamation (Thread-SMR) support.
  38 //
  39 // ThreadsListHandles are used to safely perform operations on one or more
  40 // threads without the risk of the thread or threads exiting during the
  41 // operation. It is no longer necessary to hold the Threads_lock to safely
  42 // perform an operation on a target thread.
  43 //
  44 // There are several different ways to refer to java.lang.Thread objects
  45 // so we have a few ways to get a protected JavaThread *:
  46 //
  47 // JNI jobject example:
  48 //   jobject jthread = ...;
  49 //   :
  50 //   ThreadsListHandle tlh;
  51 //   JavaThread* jt = NULL;
  52 //   bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &jt, NULL);
  53 //   if (is_alive) {
  54 //     :  // do stuff with 'jt'...


  69 //   oop thread_obj = ...;
  70 //   :
  71 //   JavaThread *jt = NULL;
  72 //   ThreadsListHandle tlh;
  73 //   jvmtiError err = JvmtiExport::cv_oop_to_JavaThread(tlh.list(), thread_obj, &jt);
  74 //   if (err != JVMTI_ERROR_NONE) {
  75 //     return err;
  76 //   }
  77 //   :  // do stuff with 'jt'...
  78 //
  79 // A JavaThread * that is included in the ThreadsList that is held by
  80 // a ThreadsListHandle is protected as long as the ThreadsListHandle
  81 // remains in scope. The target JavaThread * may have logically exited,
  82 // but that target JavaThread * will not be deleted until it is no
  83 // longer protected by a ThreadsListHandle.
  84 
  85 
  86 // SMR Support for the Threads class.
  87 //
  88 class ThreadsSMRSupport : AllStatic {
  89   friend class SafeThreadsListPtr;  // for _nested_thread_list_max, delete_notify(), release_stable_list_wake_up() access
  90 
  91   // The coordination between ThreadsSMRSupport::release_stable_list() and
  92   // ThreadsSMRSupport::smr_delete() uses the delete_lock in order to
  93   // reduce the traffic on the Threads_lock.
  94   static Monitor*              _delete_lock;
  95   // The '_cnt', '_max' and '_times" fields are enabled via
  96   // -XX:+EnableThreadSMRStatistics (see thread.cpp for a
  97   // description about each field):
  98   static uint                  _delete_lock_wait_cnt;
  99   static uint                  _delete_lock_wait_max;
 100   // The delete_notify flag is used for proper double-check
 101   // locking in order to reduce the traffic on the system wide
 102   // Thread-SMR delete_lock.
 103   static volatile uint         _delete_notify;
 104   static volatile uint         _deleted_thread_cnt;
 105   static volatile uint         _deleted_thread_time_max;
 106   static volatile uint         _deleted_thread_times;
 107   static ThreadsList* volatile _java_thread_list;
 108   static uint64_t              _java_thread_list_alloc_cnt;
 109   static uint64_t              _java_thread_list_free_cnt;
 110   static uint                  _java_thread_list_max;
 111   static uint                  _nested_thread_list_max;
 112   static volatile uint         _tlh_cnt;
 113   static volatile uint         _tlh_time_max;
 114   static volatile uint         _tlh_times;
 115   static ThreadsList*          _to_delete_list;
 116   static uint                  _to_delete_list_cnt;
 117   static uint                  _to_delete_list_max;
 118 
 119   static ThreadsList *acquire_stable_list_fast_path(Thread *self);
 120   static ThreadsList *acquire_stable_list_nested_path(Thread *self);
 121   static void add_deleted_thread_times(uint add_value);
 122   static void add_tlh_times(uint add_value);
 123   static void clear_delete_notify();
 124   static Monitor* delete_lock() { return _delete_lock; }
 125   static bool delete_notify();
 126   static void free_list(ThreadsList* threads);
 127   static void inc_deleted_thread_cnt();
 128   static void inc_java_thread_list_alloc_cnt();
 129   static void inc_tlh_cnt();
 130   static bool is_a_protected_JavaThread(JavaThread *thread);
 131   static void release_stable_list_wake_up(bool is_nested);


 132   static void set_delete_notify();
 133   static void threads_do(ThreadClosure *tc);
 134   static void threads_do(ThreadClosure *tc, ThreadsList *list);
 135   static void update_deleted_thread_time_max(uint new_value);
 136   static void update_java_thread_list_max(uint new_value);
 137   static void update_tlh_time_max(uint new_value);
 138   static void verify_hazard_ptr_scanned(Thread *self, ThreadsList *threads);
 139   static ThreadsList* xchg_java_thread_list(ThreadsList* new_list);
 140 
 141  public:

 142   static void add_thread(JavaThread *thread);
 143   static ThreadsList* get_java_thread_list();
 144   static bool is_a_protected_JavaThread_with_lock(JavaThread *thread);

 145   static void remove_thread(JavaThread *thread);
 146   static void smr_delete(JavaThread *thread);
 147   static void update_tlh_stats(uint millis);
 148 
 149   // Logging and printing support:
 150   static void log_statistics();
 151   static void print_info_elements_on(outputStream* st, ThreadsList* t_list);
 152   static void print_info_on(outputStream* st);
 153   static void print_info_on(const Thread* thread, outputStream* st);
 154 };
 155 
 156 // A fast list of JavaThreads.
 157 //
 158 class ThreadsList : public CHeapObj<mtThread> {
 159   friend class SafeThreadsListPtr;  // for {dec,inc}_nested_handle_cnt() access
 160   friend class ThreadsSMRSupport;  // for _nested_handle_cnt, {add,remove}_thread(), {,set_}next_list() access
 161 
 162   const uint _length;
 163   ThreadsList* _next_list;
 164   JavaThread *const *const _threads;
 165   volatile intx _nested_handle_cnt;
 166 
 167   template <class T>
 168   void threads_do_dispatch(T *cl, JavaThread *const thread) const;
 169 
 170   ThreadsList *next_list() const        { return _next_list; }
 171   void set_next_list(ThreadsList *list) { _next_list = list; }
 172 
 173   void inc_nested_handle_cnt();
 174   void dec_nested_handle_cnt();
 175 
 176   static ThreadsList* add_thread(ThreadsList* list, JavaThread* java_thread);
 177   static ThreadsList* remove_thread(ThreadsList* list, JavaThread* java_thread);
 178 
 179 public:
 180   ThreadsList(int entries);
 181   ~ThreadsList();
 182 
 183   template <class T>
 184   void threads_do(T *cl) const;
 185 
 186   uint length() const                       { return _length; }
 187 
 188   JavaThread *const thread_at(uint i) const { return _threads[i]; }
 189 
 190   JavaThread *const *threads() const        { return _threads; }
 191 
 192   // Returns -1 if target is not found.
 193   int find_index_of_JavaThread(JavaThread* target);
 194   JavaThread* find_JavaThread_from_java_tid(jlong java_tid) const;
 195   bool includes(const JavaThread * const p) const;
 196 };
 197 
 198 // An abstract safe ptr to a ThreadsList comprising either a stable hazard ptr
 199 // for leaves, or a retained reference count for nested uses. The user of this
 200 // API does not need to know which mechanism is providing the safety.
 201 class SafeThreadsListPtr {
 202   friend class ThreadsListSetter;
 203 
 204   SafeThreadsListPtr* _previous;
 205   Thread*                 _thread;
 206   ThreadsList*            _list;
 207   bool                    _has_ref_count;
 208   bool                    _needs_release;
 209 
 210   void acquire_stable_list();
 211   void acquire_stable_list_fast_path();
 212   void acquire_stable_list_nested_path();
 213 
 214   void release_stable_list();
 215 
 216   void verify_hazard_ptr_scanned();
 217 
 218 public:
 219   // Constructor that attaches the list onto a thread.
 220   SafeThreadsListPtr(Thread *thread, bool acquire) :
 221     _previous(NULL),
 222     _thread(thread),
 223     _list(NULL),
 224     _has_ref_count(false),
 225     _needs_release(false)
 226   {
 227     if (acquire) {
 228       acquire_stable_list();
 229     }
 230   }
 231 
 232   // Constructor that transfers ownership of the pointer.
 233   SafeThreadsListPtr(SafeThreadsListPtr& other) :
 234     _previous(other._previous),
 235     _thread(other._thread),
 236     _list(other._list),
 237     _has_ref_count(other._has_ref_count),
 238     _needs_release(other._needs_release)
 239   {
 240     other._needs_release = false;
 241   }
 242 
 243   ~SafeThreadsListPtr() {
 244     if (_needs_release) {
 245       release_stable_list();
 246     }
 247   }
 248 
 249   ThreadsList* list() const { return _list; }
 250   SafeThreadsListPtr* previous() const { return _previous; }
 251   void print_on(outputStream* st);
 252 };
 253 
 254 // A helper to optionally set the hazard ptr in ourself. This helper can
 255 // be used by ourself or by another thread. If the hazard ptr is set(),
 256 // then the destructor will release it.
 257 //
 258 class ThreadsListSetter : public StackObj {
 259 private:
 260   SafeThreadsListPtr _list_ptr;

 261 
 262 public:
 263   ThreadsListSetter() : _list_ptr(Thread::current(), /* acquire */ false) {}
 264   ThreadsList* list() { return _list_ptr.list(); }
 265   void set() { _list_ptr.acquire_stable_list(); }
 266   bool is_set() { return _list_ptr._needs_release; }


 267 };
 268 
 269 // This stack allocated ThreadsListHandle keeps all JavaThreads in the
 270 // ThreadsList from being deleted until it is safe.
 271 //
 272 class ThreadsListHandle : public StackObj {
 273   SafeThreadsListPtr _list_ptr;

 274   elapsedTimer _timer;  // Enabled via -XX:+EnableThreadSMRStatistics.
 275 
 276 public:
 277   ThreadsListHandle(Thread *self = Thread::current());
 278   ~ThreadsListHandle();
 279 
 280   ThreadsList *list() const {
 281     return _list_ptr.list();
 282   }
 283 
 284   template <class T>
 285   void threads_do(T *cl) const {
 286     return list()->threads_do(cl);
 287   }
 288 
 289   bool cv_internal_thread_to_JavaThread(jobject jthread, JavaThread ** jt_pp, oop * thread_oop_p);
 290 
 291   bool includes(JavaThread* p) {
 292     return list()->includes(p);
 293   }
 294 
 295   uint length() const {
 296     return list()->length();
 297   }
 298 };
 299 
 300 // This stack allocated JavaThreadIterator is used to walk the
 301 // specified ThreadsList using the following style:
 302 //
 303 //   JavaThreadIterator jti(t_list);
 304 //   for (JavaThread *jt = jti.first(); jt != NULL; jt = jti.next()) {
 305 //     ...
 306 //   }
 307 //
 308 class JavaThreadIterator : public StackObj {
 309   ThreadsList * _list;
 310   uint _index;
 311 
 312 public:
 313   JavaThreadIterator(ThreadsList *list) : _list(list), _index(0) {
 314     assert(list != NULL, "ThreadsList must not be NULL.");
 315   }
 316 


< prev index next >