1 /*
  2  * Copyright (c) 2017, 2021, 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/allocation.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 JavaThread;
 37 class SuspendThreadHandshake;
 38 class ThreadSelfSuspensionHandshake;
 39 
 40 // A handshake closure is a callback that is executed for a JavaThread
 41 // while it is in a safepoint/handshake-safe state. Depending on the
 42 // nature of the closure, the callback may be executed by the initiating
 43 // thread, the target thread, or the VMThread. If the callback is not executed
 44 // by the target thread it will remain in a blocked state until the callback completes.
 45 class HandshakeClosure : public ThreadClosure, public CHeapObj<mtThread> {
 46   const char* const _name;
 47  public:
 48   HandshakeClosure(const char* name) : _name(name) {}
 49   virtual ~HandshakeClosure()                      {}
 50   const char* name() const                         { return _name; }
 51   virtual bool is_async()                          { return false; }
 52   virtual bool is_suspend()                        { return false; }
 53   virtual void do_thread(Thread* thread) = 0;
 54 };
 55 
 56 class AsyncHandshakeClosure : public HandshakeClosure {
 57  public:
 58    AsyncHandshakeClosure(const char* name) : HandshakeClosure(name) {}
 59    virtual ~AsyncHandshakeClosure() {}
 60    virtual bool is_async()          { return true; }
 61 };
 62 
 63 class Handshake : public AllStatic {
 64  public:
 65   // Execution of handshake operation
 66   static void execute(HandshakeClosure*       hs_cl);
 67   static void execute(HandshakeClosure*       hs_cl, JavaThread* target);
 68   static void execute(AsyncHandshakeClosure*  hs_cl, JavaThread* target);
 69 };
 70 
 71 class JvmtiRawMonitor;
 72 
 73 // The HandshakeState keeps track of an ongoing handshake for this JavaThread.
 74 // VMThread/Handshaker and JavaThread are serialized with _lock making sure the
 75 // operation is only done by either VMThread/Handshaker on behalf of the
 76 // JavaThread or by the target JavaThread itself.
 77 class HandshakeState {
 78   friend ThreadSelfSuspensionHandshake;
 79   friend SuspendThreadHandshake;
 80   friend JavaThread;
 81   // This a back reference to the JavaThread,
 82   // the target for all operation in the queue.
 83   JavaThread* _handshakee;
 84   // The queue containing handshake operations to be performed on _handshakee.
 85   FilterQueue<HandshakeOperation*> _queue;
 86   // Provides mutual exclusion to this state and queue. Also used for
 87   // JavaThread suspend/resume operations.
 88   Monitor _lock;
 89   // Set to the thread executing the handshake operation.
 90   Thread* volatile _active_handshaker;
 91 
 92   bool claim_handshake();
 93   bool possibly_can_process_handshake();
 94   bool can_process_handshake();
 95 
 96   bool have_non_self_executable_operation();
 97   HandshakeOperation* get_op_for_self(bool allow_suspend);
 98   HandshakeOperation* get_op();
 99   void remove_op(HandshakeOperation* op);
100 
101   void set_active_handshaker(Thread* thread) { Atomic::store(&_active_handshaker, thread); }
102 
103   class MatchOp {
104     HandshakeOperation* _op;
105    public:
106     MatchOp(HandshakeOperation* op) : _op(op) {}
107     bool operator()(HandshakeOperation* op) {
108       return op == _op;
109     }
110   };
111 
112  public:
113   HandshakeState(JavaThread* thread);
114 
115   void add_operation(HandshakeOperation* op);
116 
117   bool has_operation() {
118     return !_queue.is_empty();
119   }
120   bool has_a_non_suspend_operation();
121 
122   bool operation_pending(HandshakeOperation* op);
123 
124   // If the method returns true we need to check for a possible safepoint.
125   // This is due to a suspension handshake which put the JavaThread in blocked
126   // state so a safepoint may be in-progress.
127   bool process_by_self(bool allow_suspend);
128 
129   enum ProcessResult {
130     _no_operation = 0,
131     _not_safe,
132     _claim_failed,
133     _processed,
134     _succeeded,
135     _number_states
136   };
137   ProcessResult try_process(HandshakeOperation* match_op);
138 
139   Thread* active_handshaker() const { return Atomic::load(&_active_handshaker); }
140 
141   // Suspend/resume support
142  private:
143   // This flag is true when the thread owning this
144   // HandshakeState (the _handshakee) is suspended.
145   volatile bool _suspended;
146   // This flag is true while there is async handshake (trap)
147   // on queue. Since we do only need one, we can reuse it if
148   // thread gets suspended again (after a resume)
149   // and we have not yet processed it.
150   bool _async_suspend_handshake;
151 
152   // Called from the suspend handshake.
153   bool suspend_with_handshake();
154   // Called from the async handshake (the trap)
155   // to stop a thread from continuing execution when suspended.
156   void do_self_suspend();
157 
158   bool is_suspended()                       { return Atomic::load(&_suspended); }
159   void set_suspended(bool to)               { return Atomic::store(&_suspended, to); }
160   bool has_async_suspend_handshake()        { return _async_suspend_handshake; }
161   void set_async_suspend_handshake(bool to) { _async_suspend_handshake = to; }
162 
163   bool suspend();
164   bool resume();
165 };
166 
167 #endif // SHARE_RUNTIME_HANDSHAKE_HPP