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 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'... 55 // } 56 // 57 // JVM/TI jthread example: 58 // jthread thread = ...; 59 // : 60 // JavaThread* jt = NULL; 61 // ThreadsListHandle tlh; 62 // jvmtiError err = JvmtiExport::cv_external_thread_to_JavaThread(tlh.list(), thread, &jt, NULL); 63 // if (err != JVMTI_ERROR_NONE) { 64 // return err; 65 // } 66 // : // do stuff with 'jt'... 67 // 68 // JVM/TI oop example (this one should be very rare): 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 317 JavaThread *first() { 318 _index = 0; 319 return _list->thread_at(_index); 320 } 321 322 uint length() const { 323 return _list->length(); 324 } 325 326 ThreadsList *list() const { 327 return _list; 328 } 329 330 JavaThread *next() { 331 if (++_index >= length()) { 332 return NULL; 333 } 334 return _list->thread_at(_index); 335 } 336 }; 337 338 // This stack allocated ThreadsListHandle and JavaThreadIterator combo 339 // is used to walk the ThreadsList in the included ThreadsListHandle 340 // using the following style: 341 // 342 // for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) { 343 // ... 344 // } 345 // 346 class JavaThreadIteratorWithHandle : public StackObj { 347 ThreadsListHandle _tlh; 348 uint _index; 349 350 public: 351 JavaThreadIteratorWithHandle() : _index(0) {} 352 353 uint length() const { 354 return _tlh.length(); 355 } 356 357 ThreadsList *list() const { 358 return _tlh.list(); 359 } 360 361 JavaThread *next() { 362 if (_index >= length()) { 363 return NULL; 364 } 365 return _tlh.list()->thread_at(_index++); 366 } 367 368 void rewind() { 369 _index = 0; 370 } 371 }; 372 373 #endif // SHARE_VM_RUNTIME_THREADSMR_HPP