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.hpp"
31 #include "runtime/osThread.hpp"
32 #include "runtime/semaphore.hpp"
33 #include "runtime/task.hpp"
34 #include "runtime/timerTrace.hpp"
35 #include "runtime/thread.hpp"
36 #include "runtime/vmThread.hpp"
37 #include "utilities/formatBuffer.hpp"
38 #include "utilities/preserveException.hpp"
39
40 #define ALL_JAVA_THREADS(X) for (JavaThread* X = Threads::first(); X; X = X->next())
41
42 class HandshakeOperation: public StackObj {
43 public:
44 virtual void do_handshake(JavaThread* thread) = 0;
45 virtual void cancel_handshake(JavaThread* thread) = 0;
46 };
47
48 class HandshakeThreadsOperation: public HandshakeOperation {
49 Semaphore _done;
50 ThreadClosure* _thread_cl;
51
52 public:
53 HandshakeThreadsOperation(ThreadClosure* cl) : _done(0), _thread_cl(cl) {}
54 void do_handshake(JavaThread* thread);
55 void cancel_handshake(JavaThread* thread) { _done.signal(); };
56
57 bool thread_has_completed() { return _done.trywait(); }
58 };
59
60 class VM_Handshake: public VM_Operation {
61 HandshakeThreadsOperation* const _op;
77
78 // This method returns true for threads completed their operation
79 // and true for threads canceled their operation.
80 // A cancellation can happen if the thread is exiting.
81 bool poll_for_completed_thread() { return _op->thread_has_completed(); }
82
83 bool handshake_has_timed_out(jlong start_time);
84 static void handle_timeout();
85 };
86
87 bool VM_Handshake::handshake_has_timed_out(jlong start_time) {
88 // Check if handshake operation has timed out
89 if (_handshake_timeout > 0) {
90 return os::elapsed_counter() >= (start_time + _handshake_timeout);
91 }
92 return false;
93 }
94
95 void VM_Handshake::handle_timeout() {
96 LogStreamHandle(Warning, handshake) log_stream;
97 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
98 ALL_JAVA_THREADS(thr) {
99 if (thr->has_handshake()) {
100 log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op", p2i(thr));
101 thr->print_thread_state_on(&log_stream);
102 }
103 }
104 log_stream.flush();
105 fatal("Handshake operation timed out");
106 }
107
108
109 class VM_HandshakeOneThread: public VM_Handshake {
110 JavaThread* _target;
111 bool _thread_alive;
112 public:
113 VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) :
114 VM_Handshake(op), _target(target), _thread_alive(false) {}
115
116 void doit() {
117 TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
118
119 {
120 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
121 if (Threads::includes(_target)) {
122 set_handshake(_target);
123 _thread_alive = true;
124 }
125 }
126
127 if (!_thread_alive) {
128 return;
129 }
130
131 if (!UseMembar) {
132 os::serialize_thread_states();
133 }
134
135 log_trace(handshake)("Thread signaled, begin processing by VMThtread");
136 jlong start_time = os::elapsed_counter();
137 do {
138 if (handshake_has_timed_out(start_time)) {
139 handle_timeout();
140 }
141
142 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
143 _target->handshake_process_by_vmthread();
144
145 } while (!poll_for_completed_thread());
146 }
147
148 VMOp_Type type() const { return VMOp_HandshakeOneThread; }
149
150 bool thread_alive() const { return _thread_alive; }
151 };
152
153 class VM_HandshakeAllThreads: public VM_Handshake {
154 public:
155 VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {}
156
157 void doit() {
158 TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
159
160 int number_of_threads_issued = -1;
161 int number_of_threads_completed = 0;
162 {
163 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
164 number_of_threads_issued = Threads::number_of_threads();
165
166 ALL_JAVA_THREADS(thr) {
167 set_handshake(thr);
168 }
169 }
170
171 if (!UseMembar) {
172 os::serialize_thread_states();
173 }
174
175 log_debug(handshake)("Threads signaled, begin processing blocked threads by VMThtread");
176 const jlong start_time = os::elapsed_counter();
177 do {
178 // Check if handshake operation has timed out
179 if (handshake_has_timed_out(start_time)) {
180 handle_timeout();
181 }
182
183 // Have VM thread perform the handshake operation for blocked threads.
184 // Observing a blocked state may of course be transient but the processing is guarded
185 // by semaphores and we optimistically begin by working on the blocked threads
186 {
187 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
188 ALL_JAVA_THREADS(thr) {
189 thr->handshake_process_by_vmthread();
190 }
191 }
192
193 while (poll_for_completed_thread()) {
194 number_of_threads_completed++;
195 }
196
197 } while (number_of_threads_issued != number_of_threads_completed);
198 }
199
200 VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
201 };
202
203 class VM_HandshakeFallbackOperation : public VM_Operation {
204 ThreadClosure* _thread_cl;
205 Thread* _target_thread;
206 bool _all_threads;
207 bool _thread_alive;
208 public:
209 VM_HandshakeFallbackOperation(ThreadClosure* cl) :
210 _thread_cl(cl), _target_thread(NULL), _all_threads(true), _thread_alive(true) {}
211 VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) :
212 _thread_cl(cl), _target_thread(target), _all_threads(false), _thread_alive(false) {}
213
214 void doit() {
215 ALL_JAVA_THREADS(t) {
216 if (_all_threads || t == _target_thread) {
217 if (t == _target_thread) {
218 _thread_alive = true;
219 }
220 _thread_cl->do_thread(t);
221 }
222 }
223 }
224
225 VMOp_Type type() const { return VMOp_HandshakeFallback; }
226 bool thread_alive() const { return _thread_alive; }
227 };
228
229 #undef ALL_JAVA_THREADS
230
231 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
232 ResourceMark rm;
233 FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s",
234 p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()));
235 TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task));
281 ThreadInVMForHandshake tivm(thread);
282 if (!_semaphore.trywait()) {
283 ThreadBlockInVM tbivm(thread);
284 _semaphore.wait();
285 }
286 if (has_operation()) {
287 HandshakeOperation* op = _operation;
288 clear_handshake(thread);
289 if (op != NULL) {
290 op->do_handshake(thread);
291 }
292 }
293 _semaphore.signal();
294 }
295
296 void HandshakeState::cancel_inner(JavaThread* thread) {
297 assert(Thread::current() == thread, "should call from thread");
298 assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
299 #ifdef DEBUG
300 {
301 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
302 assert(!Threads::includes(thread), "java thread must not be on threads list");
303 }
304 #endif
305 HandshakeOperation* op = _operation;
306 clear_handshake(thread);
307 if (op != NULL) {
308 op->cancel_handshake(thread);
309 }
310 }
311
312 bool HandshakeState::vmthread_can_process_handshake(JavaThread* target) {
313 return SafepointSynchronize::safepoint_safe(target, target->thread_state());
314 }
315
316 bool HandshakeState::claim_handshake_for_vmthread() {
317 if (_semaphore.trywait()) {
318 if (has_operation()) {
319 _vmthread_holds_semaphore = true;
320 } else {
321 _semaphore.signal();
322 }
|
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.hpp"
31 #include "runtime/osThread.hpp"
32 #include "runtime/semaphore.hpp"
33 #include "runtime/task.hpp"
34 #include "runtime/timerTrace.hpp"
35 #include "runtime/thread.hpp"
36 #include "runtime/vmThread.hpp"
37 #include "utilities/formatBuffer.hpp"
38 #include "utilities/preserveException.hpp"
39
40 class HandshakeOperation: public StackObj {
41 public:
42 virtual void do_handshake(JavaThread* thread) = 0;
43 virtual void cancel_handshake(JavaThread* thread) = 0;
44 };
45
46 class HandshakeThreadsOperation: public HandshakeOperation {
47 Semaphore _done;
48 ThreadClosure* _thread_cl;
49
50 public:
51 HandshakeThreadsOperation(ThreadClosure* cl) : _done(0), _thread_cl(cl) {}
52 void do_handshake(JavaThread* thread);
53 void cancel_handshake(JavaThread* thread) { _done.signal(); };
54
55 bool thread_has_completed() { return _done.trywait(); }
56 };
57
58 class VM_Handshake: public VM_Operation {
59 HandshakeThreadsOperation* const _op;
75
76 // This method returns true for threads completed their operation
77 // and true for threads canceled their operation.
78 // A cancellation can happen if the thread is exiting.
79 bool poll_for_completed_thread() { return _op->thread_has_completed(); }
80
81 bool handshake_has_timed_out(jlong start_time);
82 static void handle_timeout();
83 };
84
85 bool VM_Handshake::handshake_has_timed_out(jlong start_time) {
86 // Check if handshake operation has timed out
87 if (_handshake_timeout > 0) {
88 return os::elapsed_counter() >= (start_time + _handshake_timeout);
89 }
90 return false;
91 }
92
93 void VM_Handshake::handle_timeout() {
94 LogStreamHandle(Warning, handshake) log_stream;
95 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
96 if (thr->has_handshake()) {
97 log_stream.print("Thread " PTR_FORMAT " has not cleared its handshake op", p2i(thr));
98 thr->print_thread_state_on(&log_stream);
99 }
100 }
101 log_stream.flush();
102 fatal("Handshake operation timed out");
103 }
104
105
106 class VM_HandshakeOneThread: public VM_Handshake {
107 JavaThread* _target;
108 bool _thread_alive;
109 public:
110 VM_HandshakeOneThread(HandshakeThreadsOperation* op, JavaThread* target) :
111 VM_Handshake(op), _target(target), _thread_alive(false) {}
112
113 void doit() {
114 TraceTime timer("Performing single-target operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
115
116 {
117 ThreadsListHandle tlh;
118 if (tlh.includes(_target)) {
119 set_handshake(_target);
120 _thread_alive = true;
121 }
122 }
123
124 if (!_thread_alive) {
125 return;
126 }
127
128 if (!UseMembar) {
129 os::serialize_thread_states();
130 }
131
132 log_trace(handshake)("Thread signaled, begin processing by VMThtread");
133 jlong start_time = os::elapsed_counter();
134 do {
135 if (handshake_has_timed_out(start_time)) {
136 handle_timeout();
137 }
138
139 // We need to re-think this with SMR ThreadsList.
140 // There is an assumption in the code that the Threads_lock should be
141 // locked during certain phases.
142 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
143 ThreadsListHandle tlh;
144 if (tlh.includes(_target)) {
145 // Warning _target's address might be re-used.
146 // handshake_process_by_vmthread will check the semaphore for us again.
147 // Since we can't have more then one handshake in flight a reuse of
148 // _target's address should be okay since the new thread will not have
149 // an operation.
150 _target->handshake_process_by_vmthread();
151 } else {
152 // We can't warn here since the thread does cancel_handshake after
153 // it has been removed from the ThreadsList. So we should just keep
154 // looping here until while below returns false. If we have a bug,
155 // then we hang here, which is good for debugging.
156 }
157 } while (!poll_for_completed_thread());
158 }
159
160 VMOp_Type type() const { return VMOp_HandshakeOneThread; }
161
162 bool thread_alive() const { return _thread_alive; }
163 };
164
165 class VM_HandshakeAllThreads: public VM_Handshake {
166 public:
167 VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {}
168
169 void doit() {
170 TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
171
172 int number_of_threads_issued = 0;
173 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
174 set_handshake(thr);
175 number_of_threads_issued++;
176 }
177
178 if (number_of_threads_issued < 1) {
179 log_debug(handshake)("No threads to handshake.");
180 return;
181 }
182
183 if (!UseMembar) {
184 os::serialize_thread_states();
185 }
186
187 log_debug(handshake)("Threads signaled, begin processing blocked threads by VMThtread");
188 const jlong start_time = os::elapsed_counter();
189 int number_of_threads_completed = 0;
190 do {
191 // Check if handshake operation has timed out
192 if (handshake_has_timed_out(start_time)) {
193 handle_timeout();
194 }
195
196 // Have VM thread perform the handshake operation for blocked threads.
197 // Observing a blocked state may of course be transient but the processing is guarded
198 // by semaphores and we optimistically begin by working on the blocked threads
199 {
200 // We need to re-think this with SMR ThreadsList.
201 // There is an assumption in the code that the Threads_lock should
202 // be locked during certain phases.
203 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
204 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
205 // A new thread on the ThreadsList will not have an operation,
206 // hence it is skipped in handshake_process_by_vmthread.
207 thr->handshake_process_by_vmthread();
208 }
209 }
210
211 while (poll_for_completed_thread()) {
212 // Includes canceled operations by exiting threads.
213 number_of_threads_completed++;
214 }
215
216 } while (number_of_threads_issued != number_of_threads_completed);
217 }
218
219 VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
220 };
221
222 class VM_HandshakeFallbackOperation : public VM_Operation {
223 ThreadClosure* _thread_cl;
224 Thread* _target_thread;
225 bool _all_threads;
226 bool _thread_alive;
227 public:
228 VM_HandshakeFallbackOperation(ThreadClosure* cl) :
229 _thread_cl(cl), _target_thread(NULL), _all_threads(true), _thread_alive(true) {}
230 VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) :
231 _thread_cl(cl), _target_thread(target), _all_threads(false), _thread_alive(false) {}
232
233 void doit() {
234 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
235 if (_all_threads || t == _target_thread) {
236 if (t == _target_thread) {
237 _thread_alive = true;
238 }
239 _thread_cl->do_thread(t);
240 }
241 }
242 }
243
244 VMOp_Type type() const { return VMOp_HandshakeFallback; }
245 bool thread_alive() const { return _thread_alive; }
246 };
247
248 #undef ALL_JAVA_THREADS
249
250 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
251 ResourceMark rm;
252 FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s",
253 p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()));
254 TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task));
300 ThreadInVMForHandshake tivm(thread);
301 if (!_semaphore.trywait()) {
302 ThreadBlockInVM tbivm(thread);
303 _semaphore.wait();
304 }
305 if (has_operation()) {
306 HandshakeOperation* op = _operation;
307 clear_handshake(thread);
308 if (op != NULL) {
309 op->do_handshake(thread);
310 }
311 }
312 _semaphore.signal();
313 }
314
315 void HandshakeState::cancel_inner(JavaThread* thread) {
316 assert(Thread::current() == thread, "should call from thread");
317 assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
318 #ifdef DEBUG
319 {
320 ThreadsListHandle tlh;
321 assert(!tlh.includes(_target), "java thread must not be on threads list");
322 }
323 #endif
324 HandshakeOperation* op = _operation;
325 clear_handshake(thread);
326 if (op != NULL) {
327 op->cancel_handshake(thread);
328 }
329 }
330
331 bool HandshakeState::vmthread_can_process_handshake(JavaThread* target) {
332 return SafepointSynchronize::safepoint_safe(target, target->thread_state());
333 }
334
335 bool HandshakeState::claim_handshake_for_vmthread() {
336 if (_semaphore.trywait()) {
337 if (has_operation()) {
338 _vmthread_holds_semaphore = true;
339 } else {
340 _semaphore.signal();
341 }
|