1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 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 // Thread Safe Memory Reclamation (Thread-SMR) support. 32 // 33 // ThreadsListHandles are used to safely perform operations on one or more 34 // threads without the risk of the thread or threads exiting during the 35 // operation. It is no longer necessary to hold the Threads_lock to safely 36 // perform an operation on a target thread. 37 // 38 // There are several different ways to refer to java.lang.Thread objects 39 // so we have a few ways to get a protected JavaThread *: 40 // 41 // JNI jobject example: 42 // jobject jthread = ...; 43 // : 44 // ThreadsListHandle tlh; 45 // JavaThread* jt = NULL; 46 // bool is_alive = tlh.cv_internal_thread_to_JavaThread(jthread, &jt, NULL); 47 // if (is_alive) { 48 // : // do stuff with 'jt'... 49 // } 50 // 51 // JVM/TI jthread example: 52 // jthread thread = ...; 53 // : 54 // JavaThread* jt = NULL; 55 // ThreadsListHandle tlh; 56 // jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &jt, NULL); 57 // if (err != JVMTI_ERROR_NONE) { 58 // return err; 59 // } 60 // : // do stuff with 'jt'... 61 // 62 // JVM/TI oop example (this one should be very rare): 63 // oop thread_obj = ...; 64 // : 65 // JavaThread *jt = NULL; 66 // ThreadsListHandle tlh; 67 // jvmtiError err = JvmtiExport::cv_oop_to_JavaThread(tlh.list(), thread_obj, &jt); 68 // if (err != JVMTI_ERROR_NONE) { 69 // return err; 70 // } 71 // : // do stuff with 'jt'... 72 // 73 // A JavaThread * that is included in the ThreadsList that is held by 74 // a ThreadsListHandle is protected as long as the ThreadsListHandle 75 // remains in scope. The target JavaThread * may have logically exited, 76 // but that target JavaThread * will not be deleted until it is no 77 // longer protected by a ThreadsListHandle. 78 79 80 // SMR Support for the Threads class. 81 // 82 class ThreadsSMRSupport : AllStatic { 83 // The coordination between ThreadsSMRSupport::release_stable_list() and 84 // ThreadsSMRSupport::smr_delete() uses the delete_lock in order to 85 // reduce the traffic on the Threads_lock. 86 static Monitor* _delete_lock; 87 // The '_cnt', '_max' and '_times" fields are enabled via 88 // -XX:+EnableThreadSMRStatistics (see thread.cpp for a 89 // description about each field): 90 static uint _delete_lock_wait_cnt; 91 static uint _delete_lock_wait_max; 92 // The delete_notify flag is used for proper double-check 93 // locking in order to reduce the traffic on the system wide 94 // Thread-SMR delete_lock. 95 static volatile uint _delete_notify; 96 static volatile uint _deleted_thread_cnt; 97 static volatile uint _deleted_thread_time_max; 98 static volatile uint _deleted_thread_times; 99 static ThreadsList* volatile _java_thread_list; 100 static uint64_t _java_thread_list_alloc_cnt; 101 static uint64_t _java_thread_list_free_cnt; 102 static uint _java_thread_list_max; 103 static uint _nested_thread_list_max; 104 static volatile uint _tlh_cnt; 105 static volatile uint _tlh_time_max; 106 static volatile uint _tlh_times; 107 static ThreadsList* _to_delete_list; 108 static uint _to_delete_list_cnt; 109 static uint _to_delete_list_max; 110 111 static ThreadsList *acquire_stable_list_fast_path(Thread *self); 112 static ThreadsList *acquire_stable_list_nested_path(Thread *self); 113 static void add_deleted_thread_times(uint add_value); 114 static void add_tlh_times(uint add_value); 115 static void clear_delete_notify(); 116 static Monitor* delete_lock() { return _delete_lock; } 117 static bool delete_notify(); 118 static void free_list(ThreadsList* threads); 119 static void inc_deleted_thread_cnt(); 120 static void inc_java_thread_list_alloc_cnt(); 121 static void inc_tlh_cnt(); 122 static bool is_a_protected_JavaThread(JavaThread *thread); 123 static void release_stable_list_fast_path(Thread *self); 124 static void release_stable_list_nested_path(Thread *self); 125 static void release_stable_list_wake_up(char *log_str); 126 static void set_delete_notify(); 127 static void update_deleted_thread_time_max(uint new_value); 128 static void update_java_thread_list_max(uint new_value); 129 static void update_tlh_time_max(uint new_value); 130 static ThreadsList* xchg_java_thread_list(ThreadsList* new_list); 131 132 public: 133 static ThreadsList *acquire_stable_list(Thread *self, bool is_ThreadsListSetter); 134 static void add_thread(JavaThread *thread); 135 static ThreadsList* get_java_thread_list(); 136 static bool is_a_protected_JavaThread_with_lock(JavaThread *thread); 137 static void release_stable_list(Thread *self); 138 static void remove_thread(JavaThread *thread); 139 static void smr_delete(JavaThread *thread); 140 static void update_tlh_stats(uint millis); 141 142 // Logging and printing support: 143 static void log_statistics(); 144 static void print_info_elements_on(outputStream* st, ThreadsList* t_list); 145 static void print_info_on(outputStream* st); 146 }; 147 148 // A fast list of JavaThreads. 149 // 150 class ThreadsList : public CHeapObj<mtThread> { 151 friend class ThreadsSMRSupport; // for next_list(), set_next_list() access 152 153 const uint _length; 154 ThreadsList* _next_list; 155 JavaThread *const *const _threads; 156 157 template <class T> 158 void threads_do_dispatch(T *cl, JavaThread *const thread) const; 159 160 ThreadsList *next_list() const { return _next_list; } 161 void set_next_list(ThreadsList *list) { _next_list = list; } 162 163 static ThreadsList* add_thread(ThreadsList* list, JavaThread* java_thread); 164 static ThreadsList* remove_thread(ThreadsList* list, JavaThread* java_thread); 165 166 public: 167 ThreadsList(int entries); 168 ~ThreadsList(); 169 170 template <class T> 171 void threads_do(T *cl) const; 172 173 uint length() const { return _length; } 174 175 JavaThread *const thread_at(uint i) const { return _threads[i]; } 176 177 JavaThread *const *threads() const { return _threads; } 178 179 // Returns -1 if target is not found. 180 int find_index_of_JavaThread(JavaThread* target); 181 JavaThread* find_JavaThread_from_java_tid(jlong java_tid) const; 182 bool includes(const JavaThread * const p) const; 183 }; 184 185 // Linked list of ThreadsLists to support nested ThreadsListHandles. 186 class NestedThreadsList : public CHeapObj<mtThread> { 187 ThreadsList*const _t_list; 188 NestedThreadsList* _next; 189 190 public: 191 NestedThreadsList(ThreadsList* t_list) : _t_list(t_list) { 192 assert(Threads_lock->owned_by_self(), 193 "must own Threads_lock for saved t_list to be valid."); 194 } 195 196 ThreadsList* t_list() { return _t_list; } 197 NestedThreadsList* next() { return _next; } 198 void set_next(NestedThreadsList* value) { _next = value; } 199 }; 200 201 // A helper to optionally set the hazard ptr in ourself. This helper can 202 // be used by ourself or by another thread. If the hazard ptr is set(), 203 // then the destructor will release it. 204 // 205 class ThreadsListSetter : public StackObj { 206 private: 207 bool _target_needs_release; // needs release only when set() 208 Thread * _target; 209 210 public: 211 ThreadsListSetter() : _target_needs_release(false), _target(Thread::current()) { 212 } 213 ~ThreadsListSetter(); 214 ThreadsList* list(); 215 void set(); 216 bool target_needs_release() { return _target_needs_release; } 217 }; 218 219 // This stack allocated ThreadsListHandle keeps all JavaThreads in the 220 // ThreadsList from being deleted until it is safe. 221 // 222 class ThreadsListHandle : public StackObj { 223 ThreadsList * _list; 224 Thread *const _self; 225 elapsedTimer _timer; // Enabled via -XX:+EnableThreadSMRStatistics. 226 227 public: 228 ThreadsListHandle(Thread *self = Thread::current()); 229 ~ThreadsListHandle(); 230 231 ThreadsList *list() const { 232 return _list; 233 } 234 235 template <class T> 236 void threads_do(T *cl) const { 237 return _list->threads_do(cl); 238 } 239 240 bool cv_internal_thread_to_JavaThread(jobject jthread, JavaThread ** jt_pp, oop * thread_oop_p); 241 242 bool includes(JavaThread* p) { 243 return _list->includes(p); 244 } 245 246 uint length() const { 247 return _list->length(); 248 } 249 }; 250 251 // This stack allocated JavaThreadIterator is used to walk the 252 // specified ThreadsList using the following style: 253 // 254 // JavaThreadIterator jti(t_list); 255 // for (JavaThread *jt = jti.first(); jt != NULL; jt = jti.next()) { 256 // ... 257 // } 258 // 259 class JavaThreadIterator : public StackObj { 260 ThreadsList * _list; 261 uint _index; 262 263 public: 264 JavaThreadIterator(ThreadsList *list) : _list(list), _index(0) { 265 assert(list != NULL, "ThreadsList must not be NULL."); 266 } 267 268 JavaThread *first() { 269 _index = 0; 270 return _list->thread_at(_index); 271 } 272 273 uint length() const { 274 return _list->length(); 275 } 276 277 ThreadsList *list() const { 278 return _list; 279 } 280 281 JavaThread *next() { 282 if (++_index >= length()) { 283 return NULL; 284 } 285 return _list->thread_at(_index); 286 } 287 }; 288 289 // This stack allocated ThreadsListHandle and JavaThreadIterator combo 290 // is used to walk the ThreadsList in the included ThreadsListHandle 291 // using the following style: 292 // 293 // for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) { 294 // ... 295 // } 296 // 297 class JavaThreadIteratorWithHandle : public StackObj { 298 ThreadsListHandle _tlh; 299 uint _index; 300 301 public: 302 JavaThreadIteratorWithHandle() : _index(0) {} 303 304 uint length() const { 305 return _tlh.length(); 306 } 307 308 ThreadsList *list() const { 309 return _tlh.list(); 310 } 311 312 JavaThread *next() { 313 if (_index >= length()) { 314 return NULL; 315 } 316 return _tlh.list()->thread_at(_index++); 317 } 318 319 void rewind() { 320 _index = 0; 321 } 322 }; 323 324 #endif // SHARE_VM_RUNTIME_THREADSMR_HPP