1 /* 2 * Copyright (c) 2017, 2022, 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_RUNTIME_HANDSHAKE_HPP 26 #define SHARE_RUNTIME_HANDSHAKE_HPP 27 28 #include "memory/allStatic.hpp" 29 #include "memory/iterator.hpp" 30 #include "runtime/flags/flagSetting.hpp" 31 #include "runtime/mutex.hpp" 32 #include "runtime/orderAccess.hpp" 33 #include "utilities/filterQueue.hpp" 34 35 class HandshakeOperation; 36 class AsyncHandshakeOperation; 37 class JavaThread; 38 class SuspendThreadHandshake; 39 class ThreadSelfSuspensionHandshake; 40 class UnsafeAccessErrorHandshake; 41 class ThreadsListHandle; 42 43 // A handshake closure is a callback that is executed for a JavaThread 44 // while it is in a safepoint/handshake-safe state. Depending on the 45 // nature of the closure, the callback may be executed by the initiating 46 // thread, the target thread, or the VMThread. If the callback is not executed 47 // by the target thread it will remain in a blocked state until the callback completes. 48 class HandshakeClosure : public ThreadClosure, public CHeapObj<mtThread> { 49 const char* const _name; 50 public: 51 HandshakeClosure(const char* name) : _name(name) {} 52 virtual ~HandshakeClosure() {} 53 const char* name() const { return _name; } 54 virtual bool is_async() { return false; } 55 virtual bool is_suspend() { return false; } 56 virtual bool is_async_exception() { return false; } 57 virtual void do_thread(Thread* thread) = 0; 58 }; 59 60 class AsyncHandshakeClosure : public HandshakeClosure { 61 public: 62 AsyncHandshakeClosure(const char* name) : HandshakeClosure(name) {} 63 virtual ~AsyncHandshakeClosure() {} 64 virtual bool is_async() { return true; } 65 }; 66 67 class Handshake : public AllStatic { 68 public: 69 // Execution of handshake operation 70 static void execute(HandshakeClosure* hs_cl); 71 // This version of execute() relies on a ThreadListHandle somewhere in 72 // the caller's context to protect target (and we sanity check for that). 73 static void execute(HandshakeClosure* hs_cl, JavaThread* target); 74 // This version of execute() is used when you have a ThreadListHandle in 75 // hand and are using it to protect target. If tlh == nullptr, then we 76 // sanity check for a ThreadListHandle somewhere in the caller's context 77 // to verify that target is protected. 78 static void execute(HandshakeClosure* hs_cl, ThreadsListHandle* tlh, JavaThread* target); 79 // This version of execute() relies on a ThreadListHandle somewhere in 80 // the caller's context to protect target (and we sanity check for that). 81 static void execute(AsyncHandshakeClosure* hs_cl, JavaThread* target); 82 }; 83 84 class JvmtiRawMonitor; 85 86 // The HandshakeState keeps track of an ongoing handshake for this JavaThread. 87 // VMThread/Handshaker and JavaThread are serialized with _lock making sure the 88 // operation is only done by either VMThread/Handshaker on behalf of the 89 // JavaThread or by the target JavaThread itself. 90 class HandshakeState { 91 friend ThreadSelfSuspensionHandshake; 92 friend SuspendThreadHandshake; 93 friend UnsafeAccessErrorHandshake; 94 friend JavaThread; 95 // This a back reference to the JavaThread, 96 // the target for all operation in the queue. 97 JavaThread* _handshakee; 98 // The queue containing handshake operations to be performed on _handshakee. 99 FilterQueue<HandshakeOperation*> _queue; 100 // Provides mutual exclusion to this state and queue. Also used for 101 // JavaThread suspend/resume operations. 102 Monitor _lock; 103 // Set to the thread executing the handshake operation. 104 Thread* volatile _active_handshaker; 105 106 bool claim_handshake(); 107 bool possibly_can_process_handshake(); 108 bool can_process_handshake(); 109 110 bool has_handshaker_operation(); 111 HandshakeOperation* get_op_for_self(bool allow_suspend, bool check_async_exception); 112 HandshakeOperation* get_op_for_handshaker(); 113 void remove_op(HandshakeOperation* op); 114 115 void set_active_handshaker(Thread* thread) { Atomic::store(&_active_handshaker, thread); } 116 117 class MatchOp { 118 HandshakeOperation* _op; 119 public: 120 MatchOp(HandshakeOperation* op) : _op(op) {} 121 bool operator()(HandshakeOperation* op) { 122 return op == _op; 123 } 124 }; 125 126 public: 127 HandshakeState(JavaThread* thread); 128 ~HandshakeState(); 129 130 void add_operation(HandshakeOperation* op); 131 132 bool has_operation() { return !_queue.is_empty(); } 133 bool has_operation(bool allow_suspend, bool check_async_exception); 134 bool has_async_exception_operation(); 135 void clean_async_exception_operation(); 136 137 bool operation_pending(HandshakeOperation* op); 138 139 // If the method returns true we need to check for a possible safepoint. 140 // This is due to a suspension handshake which put the JavaThread in blocked 141 // state so a safepoint may be in-progress. 142 bool process_by_self(bool allow_suspend, bool check_async_exception); 143 144 enum ProcessResult { 145 _no_operation = 0, 146 _not_safe, 147 _claim_failed, 148 _processed, 149 _succeeded, 150 _number_states 151 }; 152 ProcessResult try_process(HandshakeOperation* match_op); 153 154 Thread* active_handshaker() const { return Atomic::load(&_active_handshaker); } 155 156 // Support for asynchronous exceptions 157 private: 158 bool _async_exceptions_blocked; 159 160 bool async_exceptions_blocked() { return _async_exceptions_blocked; } 161 void set_async_exceptions_blocked(bool b) { _async_exceptions_blocked = b; } 162 void handle_unsafe_access_error(); 163 164 // Suspend/resume support 165 private: 166 // This flag is true when the thread owning this 167 // HandshakeState (the _handshakee) is suspended. 168 volatile bool _suspended; 169 // This flag is true while there is async handshake (trap) 170 // on queue. Since we do only need one, we can reuse it if 171 // thread gets suspended again (after a resume) 172 // and we have not yet processed it. 173 bool _async_suspend_handshake; 174 175 // Called from the suspend handshake. 176 bool suspend_with_handshake(); 177 // Called from the async handshake (the trap) 178 // to stop a thread from continuing execution when suspended. 179 void do_self_suspend(); 180 181 bool is_suspended() { return Atomic::load(&_suspended); } 182 void set_suspended(bool to) { return Atomic::store(&_suspended, to); } 183 bool has_async_suspend_handshake() { return _async_suspend_handshake; } 184 void set_async_suspend_handshake(bool to) { _async_suspend_handshake = to; } 185 186 bool suspend(); 187 bool resume(); 188 }; 189 190 #endif // SHARE_RUNTIME_HANDSHAKE_HPP