author | rehn |
Fri, 29 Nov 2019 12:09:25 +0100 | |
changeset 59325 | 3636bab5e81e |
parent 59290 | 97d13893ec3c |
permissions | -rw-r--r-- |
47881 | 1 |
/* |
53775 | 2 |
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. |
47881 | 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 |
#include "precompiled.hpp" |
|
26 |
#include "logging/log.hpp" |
|
27 |
#include "logging/logStream.hpp" |
|
28 |
#include "memory/resourceArea.hpp" |
|
59290
97d13893ec3c
8234748: Clean up atomic and orderAccess includes
stefank
parents:
59273
diff
changeset
|
29 |
#include "runtime/atomic.hpp" |
47881 | 30 |
#include "runtime/handshake.hpp" |
49449
ef5d5d343e2a
8199263: Split interfaceSupport.hpp to not require including .inline.hpp files
coleenp
parents:
48105
diff
changeset
|
31 |
#include "runtime/interfaceSupport.inline.hpp" |
47881 | 32 |
#include "runtime/osThread.hpp" |
50192 | 33 |
#include "runtime/semaphore.inline.hpp" |
47881 | 34 |
#include "runtime/task.hpp" |
35 |
#include "runtime/timerTrace.hpp" |
|
36 |
#include "runtime/thread.hpp" |
|
37 |
#include "runtime/vmThread.hpp" |
|
38 |
#include "utilities/formatBuffer.hpp" |
|
39 |
#include "utilities/preserveException.hpp" |
|
40 |
||
41 |
class HandshakeOperation: public StackObj { |
|
42 |
public: |
|
43 |
virtual void do_handshake(JavaThread* thread) = 0; |
|
44 |
}; |
|
45 |
||
46 |
class HandshakeThreadsOperation: public HandshakeOperation { |
|
50626
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
47 |
static Semaphore _done; |
47881 | 48 |
ThreadClosure* _thread_cl; |
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
49 |
bool _executed; |
47881 | 50 |
public: |
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
51 |
HandshakeThreadsOperation(ThreadClosure* cl) : _thread_cl(cl), _executed(false) {} |
47881 | 52 |
void do_handshake(JavaThread* thread); |
53 |
bool thread_has_completed() { return _done.trywait(); } |
|
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
54 |
bool executed() const { return _executed; } |
50626
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
55 |
|
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
56 |
#ifdef ASSERT |
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
57 |
void check_state() { |
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
58 |
assert(!_done.trywait(), "Must be zero"); |
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
59 |
} |
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
60 |
#endif |
47881 | 61 |
}; |
62 |
||
50626
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
63 |
Semaphore HandshakeThreadsOperation::_done(0); |
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
64 |
|
47881 | 65 |
class VM_Handshake: public VM_Operation { |
66 |
const jlong _handshake_timeout; |
|
67 |
public: |
|
68 |
bool evaluate_at_safepoint() const { return false; } |
|
69 |
||
70 |
protected: |
|
50626
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
71 |
HandshakeThreadsOperation* const _op; |
47881 | 72 |
|
73 |
VM_Handshake(HandshakeThreadsOperation* op) : |
|
51334
cc2c79d22508
8208671: Runtime, JFR, Serviceability changes to allow enabling -Wreorder
tschatzl
parents:
50921
diff
changeset
|
74 |
_handshake_timeout(TimeHelper::millis_to_counter(HandshakeTimeout)), _op(op) {} |
47881 | 75 |
|
76 |
void set_handshake(JavaThread* target) { |
|
77 |
target->set_handshake_operation(_op); |
|
78 |
} |
|
79 |
||
80 |
// This method returns true for threads completed their operation |
|
81 |
// and true for threads canceled their operation. |
|
82 |
// A cancellation can happen if the thread is exiting. |
|
83 |
bool poll_for_completed_thread() { return _op->thread_has_completed(); } |
|
84 |
||
85 |
bool handshake_has_timed_out(jlong start_time); |
|
86 |
static void handle_timeout(); |
|
87 |
}; |
|
88 |
||
89 |
bool VM_Handshake::handshake_has_timed_out(jlong start_time) { |
|
90 |
// Check if handshake operation has timed out |
|
91 |
if (_handshake_timeout > 0) { |
|
92 |
return os::elapsed_counter() >= (start_time + _handshake_timeout); |
|
93 |
} |
|
94 |
return false; |
|
95 |
} |
|
96 |
||
97 |
void VM_Handshake::handle_timeout() { |
|
98 |
LogStreamHandle(Warning, handshake) log_stream; |
|
48105
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
99 |
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) { |
47881 | 100 |
if (thr->has_handshake()) { |
101 |
log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op", p2i(thr)); |
|
102 |
thr->print_thread_state_on(&log_stream); |
|
103 |
} |
|
104 |
} |
|
105 |
log_stream.flush(); |
|
106 |
fatal("Handshake operation timed out"); |
|
107 |
} |
|
108 |
||
109 |
class VM_HandshakeOneThread: public VM_Handshake { |
|
110 |
JavaThread* _target; |
|
111 |
public: |
|
112 |
VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) : |
|
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
113 |
VM_Handshake(op), _target(target) {} |
47881 | 114 |
|
115 |
void doit() { |
|
50626
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
116 |
DEBUG_ONLY(_op->check_state();) |
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
117 |
TraceTime timer("Finished executing single-target operation (VM_HandshakeOneThread::doit)", TRACETIME_LOG(Info, handshake)); |
47881 | 118 |
|
52341
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
119 |
ThreadsListHandle tlh; |
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
120 |
if (tlh.includes(_target)) { |
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
121 |
set_handshake(_target); |
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
122 |
} else { |
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
123 |
log_trace(handshake)("JavaThread " INTPTR_FORMAT " is not alive", p2i(_target)); |
47881 | 124 |
return; |
125 |
} |
|
126 |
||
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
127 |
log_trace(handshake)("JavaThread " INTPTR_FORMAT " signaled, begin attempt to process by VMThtread", p2i(_target)); |
47881 | 128 |
jlong start_time = os::elapsed_counter(); |
129 |
do { |
|
130 |
if (handshake_has_timed_out(start_time)) { |
|
131 |
handle_timeout(); |
|
132 |
} |
|
133 |
||
48105
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
134 |
// We need to re-think this with SMR ThreadsList. |
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
135 |
// There is an assumption in the code that the Threads_lock should be |
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
136 |
// locked during certain phases. |
52341
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
137 |
{ |
57699
4aea554692aa
8226228: Make Threads_lock an always safepoint checked lock.
rehn
parents:
55625
diff
changeset
|
138 |
MutexLocker ml(Threads_lock); |
48105
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
139 |
_target->handshake_process_by_vmthread(); |
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
140 |
} |
47881 | 141 |
} while (!poll_for_completed_thread()); |
50626
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
142 |
DEBUG_ONLY(_op->check_state();) |
47881 | 143 |
} |
144 |
||
145 |
VMOp_Type type() const { return VMOp_HandshakeOneThread; } |
|
146 |
||
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
147 |
bool executed() const { return _op->executed(); } |
47881 | 148 |
}; |
149 |
||
150 |
class VM_HandshakeAllThreads: public VM_Handshake { |
|
151 |
public: |
|
152 |
VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {} |
|
153 |
||
154 |
void doit() { |
|
50626
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
155 |
DEBUG_ONLY(_op->check_state();) |
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
156 |
TraceTime timer("Finished executing multi-target operation (VM_HandshakeAllThreads::doit)", TRACETIME_LOG(Info, handshake)); |
47881 | 157 |
|
52341
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
158 |
JavaThreadIteratorWithHandle jtiwh; |
48105
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
159 |
int number_of_threads_issued = 0; |
52341
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
160 |
for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) { |
48105
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
161 |
set_handshake(thr); |
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
162 |
number_of_threads_issued++; |
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
163 |
} |
47881 | 164 |
|
48105
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
165 |
if (number_of_threads_issued < 1) { |
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
166 |
log_debug(handshake)("No threads to handshake."); |
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
167 |
return; |
47881 | 168 |
} |
169 |
||
170 |
log_debug(handshake)("Threads signaled, begin processing blocked threads by VMThtread"); |
|
171 |
const jlong start_time = os::elapsed_counter(); |
|
48105
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
172 |
int number_of_threads_completed = 0; |
47881 | 173 |
do { |
174 |
// Check if handshake operation has timed out |
|
175 |
if (handshake_has_timed_out(start_time)) { |
|
176 |
handle_timeout(); |
|
177 |
} |
|
178 |
||
179 |
// Have VM thread perform the handshake operation for blocked threads. |
|
180 |
// Observing a blocked state may of course be transient but the processing is guarded |
|
181 |
// by semaphores and we optimistically begin by working on the blocked threads |
|
182 |
{ |
|
48105
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
183 |
// We need to re-think this with SMR ThreadsList. |
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
184 |
// There is an assumption in the code that the Threads_lock should |
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
185 |
// be locked during certain phases. |
52341
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
186 |
jtiwh.rewind(); |
57699
4aea554692aa
8226228: Make Threads_lock an always safepoint checked lock.
rehn
parents:
55625
diff
changeset
|
187 |
MutexLocker ml(Threads_lock); |
52341
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
188 |
for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) { |
48105
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
189 |
// A new thread on the ThreadsList will not have an operation, |
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
190 |
// hence it is skipped in handshake_process_by_vmthread. |
47881 | 191 |
thr->handshake_process_by_vmthread(); |
192 |
} |
|
193 |
} |
|
194 |
||
195 |
while (poll_for_completed_thread()) { |
|
48105
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
196 |
// Includes canceled operations by exiting threads. |
47881 | 197 |
number_of_threads_completed++; |
198 |
} |
|
199 |
||
50626
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
200 |
} while (number_of_threads_issued > number_of_threads_completed); |
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
201 |
assert(number_of_threads_issued == number_of_threads_completed, "Must be the same"); |
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
202 |
DEBUG_ONLY(_op->check_state();) |
47881 | 203 |
} |
204 |
||
205 |
VMOp_Type type() const { return VMOp_HandshakeAllThreads; } |
|
206 |
}; |
|
207 |
||
208 |
class VM_HandshakeFallbackOperation : public VM_Operation { |
|
209 |
ThreadClosure* _thread_cl; |
|
210 |
Thread* _target_thread; |
|
211 |
bool _all_threads; |
|
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
212 |
bool _executed; |
47881 | 213 |
public: |
214 |
VM_HandshakeFallbackOperation(ThreadClosure* cl) : |
|
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
215 |
_thread_cl(cl), _target_thread(NULL), _all_threads(true), _executed(false) {} |
47881 | 216 |
VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) : |
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
217 |
_thread_cl(cl), _target_thread(target), _all_threads(false), _executed(false) {} |
47881 | 218 |
|
219 |
void doit() { |
|
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
220 |
log_trace(handshake)("VMThread executing VM_HandshakeFallbackOperation"); |
48105
8d15b1369c7a
8167108: inconsistent handling of SR_lock can lead to crashes
dcubed
parents:
47881
diff
changeset
|
221 |
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { |
47881 | 222 |
if (_all_threads || t == _target_thread) { |
223 |
if (t == _target_thread) { |
|
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
224 |
_executed = true; |
47881 | 225 |
} |
226 |
_thread_cl->do_thread(t); |
|
227 |
} |
|
228 |
} |
|
229 |
} |
|
230 |
||
231 |
VMOp_Type type() const { return VMOp_HandshakeFallback; } |
|
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
232 |
bool executed() const { return _executed; } |
47881 | 233 |
}; |
234 |
||
235 |
void HandshakeThreadsOperation::do_handshake(JavaThread* thread) { |
|
236 |
ResourceMark rm; |
|
237 |
FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s", |
|
238 |
p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread())); |
|
239 |
TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task)); |
|
52341
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
240 |
|
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
241 |
// Only actually execute the operation for non terminated threads. |
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
242 |
if (!thread->is_terminated()) { |
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
243 |
_thread_cl->do_thread(thread); |
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
244 |
_executed = true; |
52341
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
245 |
} |
47881 | 246 |
|
247 |
// Use the semaphore to inform the VM thread that we have completed the operation |
|
248 |
_done.signal(); |
|
249 |
} |
|
250 |
||
251 |
void Handshake::execute(ThreadClosure* thread_cl) { |
|
252 |
if (ThreadLocalHandshakes) { |
|
253 |
HandshakeThreadsOperation cto(thread_cl); |
|
254 |
VM_HandshakeAllThreads handshake(&cto); |
|
255 |
VMThread::execute(&handshake); |
|
256 |
} else { |
|
257 |
VM_HandshakeFallbackOperation op(thread_cl); |
|
258 |
VMThread::execute(&op); |
|
259 |
} |
|
260 |
} |
|
261 |
||
262 |
bool Handshake::execute(ThreadClosure* thread_cl, JavaThread* target) { |
|
263 |
if (ThreadLocalHandshakes) { |
|
264 |
HandshakeThreadsOperation cto(thread_cl); |
|
265 |
VM_HandshakeOneThread handshake(&cto, target); |
|
266 |
VMThread::execute(&handshake); |
|
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
267 |
return handshake.executed(); |
47881 | 268 |
} else { |
269 |
VM_HandshakeFallbackOperation op(thread_cl, target); |
|
270 |
VMThread::execute(&op); |
|
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
271 |
return op.executed(); |
47881 | 272 |
} |
273 |
} |
|
274 |
||
50626
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
275 |
HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _thread_in_process_handshake(false) {} |
47881 | 276 |
|
277 |
void HandshakeState::set_operation(JavaThread* target, HandshakeOperation* op) { |
|
278 |
_operation = op; |
|
50921
7f462e8383f6
8206003: SafepointSynchronize with TLH: StoreStore barriers should be moved out of the loop
mdoerr
parents:
50626
diff
changeset
|
279 |
SafepointMechanism::arm_local_poll_release(target); |
47881 | 280 |
} |
281 |
||
282 |
void HandshakeState::clear_handshake(JavaThread* target) { |
|
283 |
_operation = NULL; |
|
54323 | 284 |
SafepointMechanism::disarm_if_needed(target, true /* release */); |
47881 | 285 |
} |
286 |
||
287 |
void HandshakeState::process_self_inner(JavaThread* thread) { |
|
288 |
assert(Thread::current() == thread, "should call from thread"); |
|
52341
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
289 |
assert(!thread->is_terminated(), "should not be a terminated thread"); |
59273
9170826a3d76
8234613: JavaThread can escape back to Java from an ongoing handshake
pchilanomate
parents:
59247
diff
changeset
|
290 |
assert(thread->thread_state() != _thread_blocked, "should not be in a blocked state"); |
9170826a3d76
8234613: JavaThread can escape back to Java from an ongoing handshake
pchilanomate
parents:
59247
diff
changeset
|
291 |
assert(thread->thread_state() != _thread_in_native, "should not be in native"); |
50626
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
292 |
|
59273
9170826a3d76
8234613: JavaThread can escape back to Java from an ongoing handshake
pchilanomate
parents:
59247
diff
changeset
|
293 |
do { |
9170826a3d76
8234613: JavaThread can escape back to Java from an ongoing handshake
pchilanomate
parents:
59247
diff
changeset
|
294 |
ThreadInVMForHandshake tivm(thread); |
9170826a3d76
8234613: JavaThread can escape back to Java from an ongoing handshake
pchilanomate
parents:
59247
diff
changeset
|
295 |
if (!_semaphore.trywait()) { |
9170826a3d76
8234613: JavaThread can escape back to Java from an ongoing handshake
pchilanomate
parents:
59247
diff
changeset
|
296 |
_semaphore.wait_with_safepoint_check(thread); |
9170826a3d76
8234613: JavaThread can escape back to Java from an ongoing handshake
pchilanomate
parents:
59247
diff
changeset
|
297 |
} |
9170826a3d76
8234613: JavaThread can escape back to Java from an ongoing handshake
pchilanomate
parents:
59247
diff
changeset
|
298 |
HandshakeOperation* op = Atomic::load_acquire(&_operation); |
9170826a3d76
8234613: JavaThread can escape back to Java from an ongoing handshake
pchilanomate
parents:
59247
diff
changeset
|
299 |
if (op != NULL) { |
9170826a3d76
8234613: JavaThread can escape back to Java from an ongoing handshake
pchilanomate
parents:
59247
diff
changeset
|
300 |
HandleMark hm(thread); |
9170826a3d76
8234613: JavaThread can escape back to Java from an ongoing handshake
pchilanomate
parents:
59247
diff
changeset
|
301 |
CautiouslyPreserveExceptionMark pem(thread); |
9170826a3d76
8234613: JavaThread can escape back to Java from an ongoing handshake
pchilanomate
parents:
59247
diff
changeset
|
302 |
// Disarm before execute the operation |
9170826a3d76
8234613: JavaThread can escape back to Java from an ongoing handshake
pchilanomate
parents:
59247
diff
changeset
|
303 |
clear_handshake(thread); |
9170826a3d76
8234613: JavaThread can escape back to Java from an ongoing handshake
pchilanomate
parents:
59247
diff
changeset
|
304 |
op->do_handshake(thread); |
9170826a3d76
8234613: JavaThread can escape back to Java from an ongoing handshake
pchilanomate
parents:
59247
diff
changeset
|
305 |
} |
9170826a3d76
8234613: JavaThread can escape back to Java from an ongoing handshake
pchilanomate
parents:
59247
diff
changeset
|
306 |
_semaphore.signal(); |
9170826a3d76
8234613: JavaThread can escape back to Java from an ongoing handshake
pchilanomate
parents:
59247
diff
changeset
|
307 |
} while (has_operation()); |
47881 | 308 |
} |
309 |
||
310 |
bool HandshakeState::vmthread_can_process_handshake(JavaThread* target) { |
|
53775 | 311 |
// handshake_safe may only be called with polls armed. |
312 |
// VM thread controls this by first claiming the handshake via claim_handshake_for_vmthread. |
|
313 |
return SafepointSynchronize::handshake_safe(target); |
|
47881 | 314 |
} |
315 |
||
52013
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
316 |
static bool possibly_vmthread_can_process_handshake(JavaThread* target) { |
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
317 |
// An externally suspended thread cannot be resumed while the |
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
318 |
// Threads_lock is held so it is safe. |
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
319 |
// Note that this method is allowed to produce false positives. |
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
320 |
assert(Threads_lock->owned_by_self(), "Not holding Threads_lock."); |
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
321 |
if (target->is_ext_suspended()) { |
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
322 |
return true; |
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
323 |
} |
52341
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
324 |
if (target->is_terminated()) { |
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
325 |
return true; |
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
326 |
} |
52013
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
327 |
switch (target->thread_state()) { |
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
328 |
case _thread_in_native: |
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
329 |
// native threads are safe if they have no java stack or have walkable stack |
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
330 |
return !target->has_last_Java_frame() || target->frame_anchor()->walkable(); |
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
331 |
|
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
332 |
case _thread_blocked: |
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
333 |
return true; |
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
334 |
|
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
335 |
default: |
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
336 |
return false; |
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
337 |
} |
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
338 |
} |
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
339 |
|
47881 | 340 |
bool HandshakeState::claim_handshake_for_vmthread() { |
50626
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
341 |
if (!_semaphore.trywait()) { |
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
342 |
return false; |
47881 | 343 |
} |
50626
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
344 |
if (has_operation()) { |
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
345 |
return true; |
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
346 |
} |
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
347 |
_semaphore.signal(); |
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
348 |
return false; |
47881 | 349 |
} |
350 |
||
351 |
void HandshakeState::process_by_vmthread(JavaThread* target) { |
|
352 |
assert(Thread::current()->is_VM_thread(), "should call from vm thread"); |
|
52341
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
353 |
// Threads_lock must be held here, but that is assert()ed in |
2b58b8e1d28f
8212933: Thread-SMR: requesting a VM operation whilst holding a ThreadsListHandle can cause deadlocks
rehn
parents:
52013
diff
changeset
|
354 |
// possibly_vmthread_can_process_handshake(). |
47881 | 355 |
|
356 |
if (!has_operation()) { |
|
357 |
// JT has already cleared its handshake |
|
358 |
return; |
|
359 |
} |
|
360 |
||
52013
92383597fa21
8210303: VM_HandshakeAllThreads fails assert with "failed: blocked and not walkable"
rehn
parents:
51432
diff
changeset
|
361 |
if (!possibly_vmthread_can_process_handshake(target)) { |
47881 | 362 |
// JT is observed in an unsafe state, it must notice the handshake itself |
363 |
return; |
|
364 |
} |
|
365 |
||
50626
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
366 |
// Claim the semaphore if there still an operation to be executed. |
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
367 |
if (!claim_handshake_for_vmthread()) { |
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
368 |
return; |
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
369 |
} |
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
370 |
|
47881 | 371 |
// If we own the semaphore at this point and while owning the semaphore |
372 |
// can observe a safe state the thread cannot possibly continue without |
|
373 |
// getting caught by the semaphore. |
|
50626
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
374 |
if (vmthread_can_process_handshake(target)) { |
47881 | 375 |
guarantee(!_semaphore.trywait(), "we should already own the semaphore"); |
55625
f7e8dbb77156
8191890: Biased locking still uses the inferior stop the world safepoint for revocation
pchilanomate
parents:
54623
diff
changeset
|
376 |
log_trace(handshake)("Processing handshake by VMThtread"); |
47881 | 377 |
_operation->do_handshake(target); |
50626
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
378 |
// Disarm after VM thread have executed the operation. |
47881 | 379 |
clear_handshake(target); |
380 |
// Release the thread |
|
381 |
} |
|
50626
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
382 |
|
9fdfe5ca0e5e
8204166: TLH: Semaphore may not be destroy until signal have returned.
rehn
parents:
50192
diff
changeset
|
383 |
_semaphore.signal(); |
47881 | 384 |
} |