1 | /* |
2 | * Copyright (c) 2017, 2019, 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 | #include "precompiled.hpp" |
26 | #include "logging/log.hpp" |
27 | #include "logging/logStream.hpp" |
28 | #include "memory/resourceArea.hpp" |
29 | #include "runtime/handshake.hpp" |
30 | #include "runtime/interfaceSupport.inline.hpp" |
31 | #include "runtime/orderAccess.hpp" |
32 | #include "runtime/osThread.hpp" |
33 | #include "runtime/semaphore.inline.hpp" |
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 { |
47 | static Semaphore _done; |
48 | ThreadClosure* _thread_cl; |
49 | |
50 | public: |
51 | HandshakeThreadsOperation(ThreadClosure* cl) : _thread_cl(cl) {} |
52 | void do_handshake(JavaThread* thread); |
53 | bool thread_has_completed() { return _done.trywait(); } |
54 | |
55 | #ifdef ASSERT |
56 | void check_state() { |
57 | assert(!_done.trywait(), "Must be zero" ); |
58 | } |
59 | #endif |
60 | }; |
61 | |
62 | Semaphore HandshakeThreadsOperation::_done(0); |
63 | |
64 | class VM_Handshake: public VM_Operation { |
65 | const jlong _handshake_timeout; |
66 | public: |
67 | bool evaluate_at_safepoint() const { return false; } |
68 | |
69 | bool evaluate_concurrently() const { return false; } |
70 | |
71 | protected: |
72 | HandshakeThreadsOperation* const _op; |
73 | |
74 | VM_Handshake(HandshakeThreadsOperation* op) : |
75 | _handshake_timeout(TimeHelper::millis_to_counter(HandshakeTimeout)), _op(op) {} |
76 | |
77 | void set_handshake(JavaThread* target) { |
78 | target->set_handshake_operation(_op); |
79 | } |
80 | |
81 | // This method returns true for threads completed their operation |
82 | // and true for threads canceled their operation. |
83 | // A cancellation can happen if the thread is exiting. |
84 | bool poll_for_completed_thread() { return _op->thread_has_completed(); } |
85 | |
86 | bool handshake_has_timed_out(jlong start_time); |
87 | static void handle_timeout(); |
88 | }; |
89 | |
90 | bool VM_Handshake::handshake_has_timed_out(jlong start_time) { |
91 | // Check if handshake operation has timed out |
92 | if (_handshake_timeout > 0) { |
93 | return os::elapsed_counter() >= (start_time + _handshake_timeout); |
94 | } |
95 | return false; |
96 | } |
97 | |
98 | void VM_Handshake::handle_timeout() { |
99 | LogStreamHandle(Warning, handshake) log_stream; |
100 | for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) { |
101 | if (thr->has_handshake()) { |
102 | log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op" , p2i(thr)); |
103 | thr->print_thread_state_on(&log_stream); |
104 | } |
105 | } |
106 | log_stream.flush(); |
107 | fatal("Handshake operation timed out" ); |
108 | } |
109 | |
110 | class VM_HandshakeOneThread: public VM_Handshake { |
111 | JavaThread* _target; |
112 | bool _thread_alive; |
113 | public: |
114 | VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) : |
115 | VM_Handshake(op), _target(target), _thread_alive(false) {} |
116 | |
117 | void doit() { |
118 | DEBUG_ONLY(_op->check_state();) |
119 | TraceTime timer("Performing single-target operation (vmoperation doit)" , TRACETIME_LOG(Info, handshake)); |
120 | |
121 | ThreadsListHandle tlh; |
122 | if (tlh.includes(_target)) { |
123 | set_handshake(_target); |
124 | _thread_alive = true; |
125 | } else { |
126 | return; |
127 | } |
128 | |
129 | log_trace(handshake)("Thread signaled, begin processing by VMThtread" ); |
130 | jlong start_time = os::elapsed_counter(); |
131 | do { |
132 | if (handshake_has_timed_out(start_time)) { |
133 | handle_timeout(); |
134 | } |
135 | |
136 | // We need to re-think this with SMR ThreadsList. |
137 | // There is an assumption in the code that the Threads_lock should be |
138 | // locked during certain phases. |
139 | { |
140 | MutexLocker ml(Threads_lock, Mutex::_no_safepoint_check_flag); |
141 | _target->handshake_process_by_vmthread(); |
142 | } |
143 | } while (!poll_for_completed_thread()); |
144 | DEBUG_ONLY(_op->check_state();) |
145 | } |
146 | |
147 | VMOp_Type type() const { return VMOp_HandshakeOneThread; } |
148 | |
149 | bool thread_alive() const { return _thread_alive; } |
150 | }; |
151 | |
152 | class VM_HandshakeAllThreads: public VM_Handshake { |
153 | public: |
154 | VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {} |
155 | |
156 | void doit() { |
157 | DEBUG_ONLY(_op->check_state();) |
158 | TraceTime timer("Performing operation (vmoperation doit)" , TRACETIME_LOG(Info, handshake)); |
159 | |
160 | JavaThreadIteratorWithHandle jtiwh; |
161 | int number_of_threads_issued = 0; |
162 | for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) { |
163 | set_handshake(thr); |
164 | number_of_threads_issued++; |
165 | } |
166 | |
167 | if (number_of_threads_issued < 1) { |
168 | log_debug(handshake)("No threads to handshake." ); |
169 | return; |
170 | } |
171 | |
172 | log_debug(handshake)("Threads signaled, begin processing blocked threads by VMThtread" ); |
173 | const jlong start_time = os::elapsed_counter(); |
174 | int number_of_threads_completed = 0; |
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 | { |
185 | // We need to re-think this with SMR ThreadsList. |
186 | // There is an assumption in the code that the Threads_lock should |
187 | // be locked during certain phases. |
188 | jtiwh.rewind(); |
189 | MutexLocker ml(Threads_lock, Mutex::_no_safepoint_check_flag); |
190 | for (JavaThread *thr = jtiwh.next(); thr != NULL; thr = jtiwh.next()) { |
191 | // A new thread on the ThreadsList will not have an operation, |
192 | // hence it is skipped in handshake_process_by_vmthread. |
193 | thr->handshake_process_by_vmthread(); |
194 | } |
195 | } |
196 | |
197 | while (poll_for_completed_thread()) { |
198 | // Includes canceled operations by exiting threads. |
199 | number_of_threads_completed++; |
200 | } |
201 | |
202 | } while (number_of_threads_issued > number_of_threads_completed); |
203 | assert(number_of_threads_issued == number_of_threads_completed, "Must be the same" ); |
204 | DEBUG_ONLY(_op->check_state();) |
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; |
214 | bool _thread_alive; |
215 | public: |
216 | VM_HandshakeFallbackOperation(ThreadClosure* cl) : |
217 | _thread_cl(cl), _target_thread(NULL), _all_threads(true), _thread_alive(true) {} |
218 | VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) : |
219 | _thread_cl(cl), _target_thread(target), _all_threads(false), _thread_alive(false) {} |
220 | |
221 | void doit() { |
222 | for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { |
223 | if (_all_threads || t == _target_thread) { |
224 | if (t == _target_thread) { |
225 | _thread_alive = true; |
226 | } |
227 | _thread_cl->do_thread(t); |
228 | } |
229 | } |
230 | } |
231 | |
232 | VMOp_Type type() const { return VMOp_HandshakeFallback; } |
233 | bool thread_alive() const { return _thread_alive; } |
234 | }; |
235 | |
236 | void HandshakeThreadsOperation::do_handshake(JavaThread* thread) { |
237 | ResourceMark rm; |
238 | FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s" , |
239 | p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread())); |
240 | TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task)); |
241 | |
242 | // Only actually execute the operation for non terminated threads. |
243 | if (!thread->is_terminated()) { |
244 | _thread_cl->do_thread(thread); |
245 | } |
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); |
267 | return handshake.thread_alive(); |
268 | } else { |
269 | VM_HandshakeFallbackOperation op(thread_cl, target); |
270 | VMThread::execute(&op); |
271 | return op.thread_alive(); |
272 | } |
273 | } |
274 | |
275 | HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _thread_in_process_handshake(false) {} |
276 | |
277 | void HandshakeState::set_operation(JavaThread* target, HandshakeOperation* op) { |
278 | _operation = op; |
279 | SafepointMechanism::arm_local_poll_release(target); |
280 | } |
281 | |
282 | void HandshakeState::clear_handshake(JavaThread* target) { |
283 | _operation = NULL; |
284 | SafepointMechanism::disarm_if_needed(target, true /* release */); |
285 | } |
286 | |
287 | void HandshakeState::process_self_inner(JavaThread* thread) { |
288 | assert(Thread::current() == thread, "should call from thread" ); |
289 | assert(!thread->is_terminated(), "should not be a terminated thread" ); |
290 | |
291 | ThreadInVMForHandshake tivm(thread); |
292 | if (!_semaphore.trywait()) { |
293 | _semaphore.wait_with_safepoint_check(thread); |
294 | } |
295 | HandshakeOperation* op = OrderAccess::load_acquire(&_operation); |
296 | if (op != NULL) { |
297 | HandleMark hm(thread); |
298 | CautiouslyPreserveExceptionMark pem(thread); |
299 | // Disarm before execute the operation |
300 | clear_handshake(thread); |
301 | op->do_handshake(thread); |
302 | } |
303 | _semaphore.signal(); |
304 | } |
305 | |
306 | bool HandshakeState::vmthread_can_process_handshake(JavaThread* target) { |
307 | // handshake_safe may only be called with polls armed. |
308 | // VM thread controls this by first claiming the handshake via claim_handshake_for_vmthread. |
309 | return SafepointSynchronize::handshake_safe(target); |
310 | } |
311 | |
312 | static bool possibly_vmthread_can_process_handshake(JavaThread* target) { |
313 | // An externally suspended thread cannot be resumed while the |
314 | // Threads_lock is held so it is safe. |
315 | // Note that this method is allowed to produce false positives. |
316 | assert(Threads_lock->owned_by_self(), "Not holding Threads_lock." ); |
317 | if (target->is_ext_suspended()) { |
318 | return true; |
319 | } |
320 | if (target->is_terminated()) { |
321 | return true; |
322 | } |
323 | switch (target->thread_state()) { |
324 | case _thread_in_native: |
325 | // native threads are safe if they have no java stack or have walkable stack |
326 | return !target->has_last_Java_frame() || target->frame_anchor()->walkable(); |
327 | |
328 | case _thread_blocked: |
329 | return true; |
330 | |
331 | default: |
332 | return false; |
333 | } |
334 | } |
335 | |
336 | bool HandshakeState::claim_handshake_for_vmthread() { |
337 | if (!_semaphore.trywait()) { |
338 | return false; |
339 | } |
340 | if (has_operation()) { |
341 | return true; |
342 | } |
343 | _semaphore.signal(); |
344 | return false; |
345 | } |
346 | |
347 | void HandshakeState::process_by_vmthread(JavaThread* target) { |
348 | assert(Thread::current()->is_VM_thread(), "should call from vm thread" ); |
349 | // Threads_lock must be held here, but that is assert()ed in |
350 | // possibly_vmthread_can_process_handshake(). |
351 | |
352 | if (!has_operation()) { |
353 | // JT has already cleared its handshake |
354 | return; |
355 | } |
356 | |
357 | if (!possibly_vmthread_can_process_handshake(target)) { |
358 | // JT is observed in an unsafe state, it must notice the handshake itself |
359 | return; |
360 | } |
361 | |
362 | // Claim the semaphore if there still an operation to be executed. |
363 | if (!claim_handshake_for_vmthread()) { |
364 | return; |
365 | } |
366 | |
367 | // If we own the semaphore at this point and while owning the semaphore |
368 | // can observe a safe state the thread cannot possibly continue without |
369 | // getting caught by the semaphore. |
370 | if (vmthread_can_process_handshake(target)) { |
371 | guarantee(!_semaphore.trywait(), "we should already own the semaphore" ); |
372 | _operation->do_handshake(target); |
373 | // Disarm after VM thread have executed the operation. |
374 | clear_handshake(target); |
375 | // Release the thread |
376 | } |
377 | |
378 | _semaphore.signal(); |
379 | } |
380 | |