Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/src/hotspot/share/runtime/handshake.hpp
64440 views
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
168
169