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