Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/runtime/handshake.hpp
40951 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 "utilities/filterQueue.hpp"
33
34
class HandshakeOperation;
35
class JavaThread;
36
class SuspendThreadHandshake;
37
class ThreadSelfSuspensionHandshake;
38
39
// A handshake closure is a callback that is executed for a JavaThread
40
// while it is in a safepoint/handshake-safe state. Depending on the
41
// nature of the closure, the callback may be executed by the initiating
42
// thread, the target thread, or the VMThread. If the callback is not executed
43
// by the target thread it will remain in a blocked state until the callback completes.
44
class HandshakeClosure : public ThreadClosure, public CHeapObj<mtThread> {
45
const char* const _name;
46
public:
47
HandshakeClosure(const char* name) : _name(name) {}
48
virtual ~HandshakeClosure() {}
49
const char* name() const { return _name; }
50
virtual bool is_async() { return false; }
51
virtual void do_thread(Thread* thread) = 0;
52
};
53
54
class AsyncHandshakeClosure : public HandshakeClosure {
55
public:
56
AsyncHandshakeClosure(const char* name) : HandshakeClosure(name) {}
57
virtual ~AsyncHandshakeClosure() {}
58
virtual bool is_async() { return true; }
59
};
60
61
class Handshake : public AllStatic {
62
public:
63
// Execution of handshake operation
64
static void execute(HandshakeClosure* hs_cl);
65
static void execute(HandshakeClosure* hs_cl, JavaThread* target);
66
static void execute(AsyncHandshakeClosure* hs_cl, JavaThread* target);
67
};
68
69
class JvmtiRawMonitor;
70
71
// The HandshakeState keeps track of an ongoing handshake for this JavaThread.
72
// VMThread/Handshaker and JavaThread are serialized with _lock making sure the
73
// operation is only done by either VMThread/Handshaker on behalf of the
74
// JavaThread or by the target JavaThread itself.
75
class HandshakeState {
76
friend ThreadSelfSuspensionHandshake;
77
friend SuspendThreadHandshake;
78
friend JavaThread;
79
// This a back reference to the JavaThread,
80
// the target for all operation in the queue.
81
JavaThread* _handshakee;
82
// The queue containing handshake operations to be performed on _handshakee.
83
FilterQueue<HandshakeOperation*> _queue;
84
// Provides mutual exclusion to this state and queue. Also used for
85
// JavaThread suspend/resume operations.
86
Monitor _lock;
87
// Set to the thread executing the handshake operation.
88
Thread* _active_handshaker;
89
90
bool claim_handshake();
91
bool possibly_can_process_handshake();
92
bool can_process_handshake();
93
94
// Returns false if the JavaThread finished all its handshake operations.
95
// If the method returns true there is still potential work to be done,
96
// but we need to check for a safepoint before.
97
// (This is due to a suspension handshake which put the JavaThread in blocked
98
// state so a safepoint may be in-progress.)
99
bool process_self_inner();
100
101
bool have_non_self_executable_operation();
102
HandshakeOperation* pop_for_self();
103
HandshakeOperation* pop();
104
105
public:
106
HandshakeState(JavaThread* thread);
107
108
void add_operation(HandshakeOperation* op);
109
110
bool has_operation() {
111
return !_queue.is_empty();
112
}
113
114
bool operation_pending(HandshakeOperation* op);
115
116
// Both _queue and _lock must be checked. If a thread has seen this _handshakee
117
// as safe it will execute all possible handshake operations in a loop while
118
// holding _lock. We use lock free addition to the queue, which means it is
119
// possible for the queue to be seen as empty by _handshakee but as non-empty
120
// by the thread executing in the loop. To avoid the _handshakee continuing
121
// while handshake operations are being executed, the _handshakee
122
// must take slow path, process_by_self(), if _lock is held.
123
bool should_process() {
124
// The holder of the _lock can add an asynchronous handshake to queue.
125
// To make sure it is seen by the handshakee, the handshakee must first
126
// check the _lock, and if held go to slow path.
127
// Since the handshakee is unsafe if _lock gets locked after this check
128
// we know other threads cannot process any handshakes.
129
// Now we can check the queue to see if there is anything we should processs.
130
if (_lock.is_locked()) {
131
return true;
132
}
133
// Lock check must be done before queue check, force ordering.
134
OrderAccess::loadload();
135
return !_queue.is_empty();
136
}
137
138
bool process_by_self();
139
140
enum ProcessResult {
141
_no_operation = 0,
142
_not_safe,
143
_claim_failed,
144
_processed,
145
_succeeded,
146
_number_states
147
};
148
ProcessResult try_process(HandshakeOperation* match_op);
149
150
Thread* active_handshaker() const { return _active_handshaker; }
151
152
// Suspend/resume support
153
private:
154
// This flag is true when the thread owning this
155
// HandshakeState (the _handshakee) is suspended.
156
volatile bool _suspended;
157
// This flag is true while there is async handshake (trap)
158
// on queue. Since we do only need one, we can reuse it if
159
// thread gets suspended again (after a resume)
160
// and we have not yet processed it.
161
bool _async_suspend_handshake;
162
163
// Called from the suspend handshake.
164
bool suspend_with_handshake();
165
// Called from the async handshake (the trap)
166
// to stop a thread from continuing execution when suspended.
167
void do_self_suspend();
168
169
bool is_suspended() { return Atomic::load(&_suspended); }
170
void set_suspended(bool to) { return Atomic::store(&_suspended, to); }
171
bool has_async_suspend_handshake() { return _async_suspend_handshake; }
172
void set_async_suspend_handshake(bool to) { _async_suspend_handshake = to; }
173
174
bool suspend();
175
bool resume();
176
};
177
178
#endif // SHARE_RUNTIME_HANDSHAKE_HPP
179
180