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