1 /* 2 * Copyright (c) 2017, 2018, 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 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'... 51 // } 52 // 53 // JVM/TI jthread example: 54 // jthread thread = ...; 55 // : 56 // JavaThread* jt = NULL; 57 // ThreadsListHandle tlh; 58 // jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &jt, NULL); 59 // if (err != JVMTI_ERROR_NONE) { 60 // return err; 61 // } 62 // : // do stuff with 'jt'... 63 // 64 // JVM/TI oop example (this one should be very rare): 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 273 JavaThread *first() { 274 _index = 0; 275 return _list->thread_at(_index); 276 } 277 278 uint length() const { 279 return _list->length(); 280 } 281 282 ThreadsList *list() const { 283 return _list; 284 } 285 286 JavaThread *next() { 287 if (++_index >= length()) { 288 return NULL; 289 } 290 return _list->thread_at(_index); 291 } 292 }; 293 294 // This stack allocated ThreadsListHandle and JavaThreadIterator combo 295 // is used to walk the ThreadsList in the included ThreadsListHandle 296 // using the following style: 297 // 298 // for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) { 299 // ... 300 // } 301 // 302 class JavaThreadIteratorWithHandle : public StackObj { 303 ThreadsListHandle _tlh; 304 uint _index; 305 306 public: 307 JavaThreadIteratorWithHandle() : _index(0) {} 308 309 uint length() const { 310 return _tlh.length(); 311 } 312 313 ThreadsList *list() const { 314 return _tlh.list(); 315 } 316 317 JavaThread *next() { 318 if (_index >= length()) { 319 return NULL; 320 } 321 return _tlh.list()->thread_at(_index++); 322 } 323 324 void rewind() { 325 _index = 0; 326 } 327 }; 328 329 #endif // SHARE_VM_RUNTIME_THREADSMR_HPP