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 assumption in code that Threads_lock should be lock
141 // during certain phases.
142 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
143 ThreadsListHandle tlh;
144 if (tlh.includes(_target)) {
145 // Warning threads 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 thread address
148 // should be okey since the new thread will not have an operation.
149 _target->handshake_process_by_vmthread();
150 } else {
151 // We can't warn here is since the thread do cancel_handshake after it have been removed
152 // from ThreadsList. So we should just keep looping here until while below return negative
153 // If we have a bug, then we deadlock here, which is good for debugging.
154 }
155
156 } while (!poll_for_completed_thread());
157 }
158
159 VMOp_Type type() const { return VMOp_HandshakeOneThread; }
160
161 bool thread_alive() const { return _thread_alive; }
162 };
163
164 class VM_HandshakeAllThreads: public VM_Handshake {
165 public:
166 VM_HandshakeAllThreads(HandshakeThreadsOperation* op) : VM_Handshake(op) {}
167
168 void doit() {
169 TraceTime timer("Performing operation (vmoperation doit)", TRACETIME_LOG(Info, handshake));
170
171 int number_of_threads_issued = 0;
172 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
173 set_handshake(thr);
174 number_of_threads_issued++;
175 }
176
177 if (number_of_threads_issued < 1) {
178 log_debug(handshake)("No threads to handshake.");
179 return;
180 }
181
182 if (!UseMembar) {
183 os::serialize_thread_states();
184 }
185
186 log_debug(handshake)("Threads signaled, begin processing blocked threads by VMThtread");
187 const jlong start_time = os::elapsed_counter();
188 int number_of_threads_completed = 0;
189 do {
190 // Check if handshake operation has timed out
191 if (handshake_has_timed_out(start_time)) {
192 handle_timeout();
193 }
194
195 // Have VM thread perform the handshake operation for blocked threads.
196 // Observing a blocked state may of course be transient but the processing is guarded
197 // by semaphores and we optimistically begin by working on the blocked threads
198 {
199 // We need to re-think this with SMR ThreadsList.
200 // There is assumption in code that Threads_lock should be lock
201 // during certain phases.
202 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag);
203 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thr = jtiwh.next(); ) {
204 // A new thread on the ThreadsList will not have an operation.
205 // Hence is skipped in handshake_process_by_vmthread.
206 thr->handshake_process_by_vmthread();
207 }
208 }
209
210 while (poll_for_completed_thread()) {
211 // Includes canceled operations by exiting threads.
212 number_of_threads_completed++;
213 }
214
215 } while (number_of_threads_issued != number_of_threads_completed);
216 }
217
218 VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
219 };
220
221 class VM_HandshakeFallbackOperation : public VM_Operation {
222 ThreadClosure* _thread_cl;
223 Thread* _target_thread;
224 bool _all_threads;
225 bool _thread_alive;
226 public:
227 VM_HandshakeFallbackOperation(ThreadClosure* cl) :
228 _thread_cl(cl), _target_thread(NULL), _all_threads(true), _thread_alive(true) {}
229 VM_HandshakeFallbackOperation(ThreadClosure* cl, Thread* target) :
230 _thread_cl(cl), _target_thread(target), _all_threads(false), _thread_alive(false) {}
231
232 void doit() {
233 for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
234 if (_all_threads || t == _target_thread) {
235 if (t == _target_thread) {
236 _thread_alive = true;
237 }
238 _thread_cl->do_thread(t);
239 }
240 }
241 }
242
243 VMOp_Type type() const { return VMOp_HandshakeFallback; }
244 bool thread_alive() const { return _thread_alive; }
245 };
246
247 #undef ALL_JAVA_THREADS
248
249 void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
250 ResourceMark rm;
251 FormatBufferResource message("Operation for thread " PTR_FORMAT ", is_vm_thread: %s",
252 p2i(thread), BOOL_TO_STR(Thread::current()->is_VM_thread()));
253 TraceTime timer(message, TRACETIME_LOG(Debug, handshake, task));
299 ThreadInVMForHandshake tivm(thread);
300 if (!_semaphore.trywait()) {
301 ThreadBlockInVM tbivm(thread);
302 _semaphore.wait();
303 }
304 if (has_operation()) {
305 HandshakeOperation* op = _operation;
306 clear_handshake(thread);
307 if (op != NULL) {
308 op->do_handshake(thread);
309 }
310 }
311 _semaphore.signal();
312 }
313
314 void HandshakeState::cancel_inner(JavaThread* thread) {
315 assert(Thread::current() == thread, "should call from thread");
316 assert(thread->thread_state() == _thread_in_vm, "must be in vm state");
317 #ifdef DEBUG
318 {
319 ThreadsListHandle tlh;
320 assert(!tlh.includes(_target), "java thread must not be on threads list");
321 }
322 #endif
323 HandshakeOperation* op = _operation;
324 clear_handshake(thread);
325 if (op != NULL) {
326 op->cancel_handshake(thread);
327 }
328 }
329
330 bool HandshakeState::vmthread_can_process_handshake(JavaThread* target) {
331 return SafepointSynchronize::safepoint_safe(target, target->thread_state());
332 }
333
334 bool HandshakeState::claim_handshake_for_vmthread() {
335 if (_semaphore.trywait()) {
336 if (has_operation()) {
337 _vmthread_holds_semaphore = true;
338 } else {
339 _semaphore.signal();
340 }
|