1 /*
2 * Copyright (c) 2003, 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 "memory/allocation.inline.hpp"
27 #include "prims/jvmtiRawMonitor.hpp"
28 #include "runtime/atomic.hpp"
29 #include "runtime/interfaceSupport.inline.hpp"
30 #include "runtime/orderAccess.hpp"
31 #include "runtime/thread.inline.hpp"
32
33 JvmtiRawMonitor::QNode::QNode(Thread* thread) : _next(NULL), _prev(NULL),
34 _event(thread->_ParkEvent),
35 _notified(0), _t_state(TS_RUN) {
36 }
37
38 GrowableArray<JvmtiRawMonitor*>* JvmtiPendingMonitors::_monitors =
39 new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiRawMonitor*>(1, true);
40
41 void JvmtiPendingMonitors::transition_raw_monitors() {
42 assert((Threads::number_of_threads()==1),
43 "Java thread has not been created yet or more than one java thread "
44 "is running. Raw monitor transition will not work");
45 JavaThread* current_java_thread = JavaThread::current();
46 assert(current_java_thread->thread_state() == _thread_in_vm, "Must be in vm");
47 for (int i = 0; i < count(); i++) {
48 JvmtiRawMonitor* rmonitor = monitors()->at(i);
49 rmonitor->raw_enter(current_java_thread);
50 }
51 // pending monitors are converted to real monitor so delete them all.
52 dispose();
53 }
54
55 //
56 // class JvmtiRawMonitor
57 //
58
59 JvmtiRawMonitor::JvmtiRawMonitor(const char* name) : _owner(NULL),
60 _recursions(0),
61 _entry_list(NULL),
62 _wait_set(NULL),
63 _waiters(0),
64 _magic(JVMTI_RM_MAGIC),
65 _name(NULL) {
66 #ifdef ASSERT
67 _name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtInternal), name);
68 #endif
69 }
70
71 JvmtiRawMonitor::~JvmtiRawMonitor() {
72 #ifdef ASSERT
73 FreeHeap(_name);
74 #endif
75 _magic = 0;
76 }
77
78
79 bool
80 JvmtiRawMonitor::is_valid() {
81 int value = 0;
82
83 // This object might not be a JvmtiRawMonitor so we can't assume
84 // the _magic field is properly aligned. Get the value in a safe
85 // way and then check against JVMTI_RM_MAGIC.
86
87 switch (sizeof(_magic)) {
88 case 2:
89 value = Bytes::get_native_u2((address)&_magic);
90 break;
91
92 case 4:
93 value = Bytes::get_native_u4((address)&_magic);
94 break;
95
96 case 8:
97 value = Bytes::get_native_u8((address)&_magic);
98 break;
99
100 default:
101 guarantee(false, "_magic field is an unexpected size");
102 }
103
104 return value == JVMTI_RM_MAGIC;
105 }
106
107 // -------------------------------------------------------------------------
108 // The JVMTI raw monitor subsystem is entirely distinct from normal
109 // java-synchronization or jni-synchronization. JVMTI raw monitors are not
110 // associated with objects. They can be implemented in any manner
111 // that makes sense. The original implementors decided to piggy-back
112 // the raw-monitor implementation on the existing Java ObjectMonitor mechanism.
113 // Now we just use a simplified form of that ObjectMonitor code.
114 //
115 // Note that we use the single RawMonitor_lock to protect queue operations for
116 // _all_ raw monitors. This is a scalability impediment, but since raw monitor usage
117 // is fairly rare, this is not of concern. The RawMonitor_lock can not
118 // be held indefinitely. The critical sections must be short and bounded.
119 //
120 // -------------------------------------------------------------------------
121
122 void JvmtiRawMonitor::simple_enter(Thread* self) {
123 for (;;) {
124 if (Atomic::replace_if_null(&_owner, self)) {
125 return;
126 }
127
128 QNode node(self);
129 self->_ParkEvent->reset(); // strictly optional
130 node._t_state = QNode::TS_ENTER;
131
132 RawMonitor_lock->lock_without_safepoint_check();
133 node._next = _entry_list;
134 _entry_list = &node;
135 OrderAccess::fence();
136 if (_owner == NULL && Atomic::replace_if_null(&_owner, self)) {
137 _entry_list = node._next;
138 RawMonitor_lock->unlock();
139 return;
140 }
141 RawMonitor_lock->unlock();
142 while (node._t_state == QNode::TS_ENTER) {
143 self->_ParkEvent->park();
144 }
145 }
146 }
147
148 void JvmtiRawMonitor::simple_exit(Thread* self) {
149 guarantee(_owner == self, "invariant");
150 Atomic::release_store(&_owner, (Thread*)NULL);
151 OrderAccess::fence();
152 if (_entry_list == NULL) {
153 return;
154 }
155
156 RawMonitor_lock->lock_without_safepoint_check();
157 QNode* w = _entry_list;
158 if (w != NULL) {
159 _entry_list = w->_next;
160 }
161 RawMonitor_lock->unlock();
162 if (w != NULL) {
163 guarantee(w ->_t_state == QNode::TS_ENTER, "invariant");
164 // Once we set _t_state to TS_RUN the waiting thread can complete
165 // simple_enter and 'w' is pointing into random stack space. So we have
166 // to ensure we extract the ParkEvent (which is in type-stable memory)
167 // before we set the state, and then don't access 'w'.
168 ParkEvent* ev = w->_event;
169 OrderAccess::loadstore();
170 w->_t_state = QNode::TS_RUN;
171 OrderAccess::fence();
172 ev->unpark();
173 }
174 return;
175 }
176
177 inline void JvmtiRawMonitor::enqueue_waiter(QNode& node) {
178 node._notified = 0;
179 node._t_state = QNode::TS_WAIT;
180 RawMonitor_lock->lock_without_safepoint_check();
181 node._next = _wait_set;
182 _wait_set = &node;
183 RawMonitor_lock->unlock();
184 }
185
186 inline void JvmtiRawMonitor::dequeue_waiter(QNode& node) {
187 // If thread still resides on the waitset then unlink it.
188 // Double-checked locking -- the usage is safe in this context
189 // as _t_state is volatile and the lock-unlock operators are
190 // serializing (barrier-equivalent).
191
192 if (node._t_state == QNode::TS_WAIT) {
193 RawMonitor_lock->lock_without_safepoint_check();
194 if (node._t_state == QNode::TS_WAIT) {
195 // Simple O(n) unlink, but performance isn't critical here.
196 QNode* p;
197 QNode* q = NULL;
198 for (p = _wait_set; p != &node; p = p->_next) {
199 q = p;
200 }
201 guarantee(p == &node, "invariant");
202 if (q == NULL) {
203 guarantee (p == _wait_set, "invariant");
204 _wait_set = p->_next;
205 } else {
206 guarantee(p == q->_next, "invariant");
207 q->_next = p->_next;
208 }
209 node._t_state = QNode::TS_RUN;
210 }
211 RawMonitor_lock->unlock();
212 }
213
214 guarantee(node._t_state == QNode::TS_RUN, "invariant");
215 }
216
217 // simple_wait is not quite so simple as we have to deal with the interaction
218 // with the Thread interrupt state, which resides in the java.lang.Thread object.
219 // That state must only be accessed while _thread_in_vm and requires proper thread-state
220 // transitions. However, we cannot perform such transitions whilst we hold the RawMonitor,
221 // else we can deadlock with the VMThread (which may also use RawMonitors as part of
222 // executing various callbacks).
223 // Returns M_OK usually, but M_INTERRUPTED if the thread is a JavaThread and was
224 // interrupted.
225 int JvmtiRawMonitor::simple_wait(Thread* self, jlong millis) {
226 guarantee(_owner == self , "invariant");
227 guarantee(_recursions == 0, "invariant");
228
229 QNode node(self);
230 enqueue_waiter(node);
231
232 simple_exit(self);
233 guarantee(_owner != self, "invariant");
234
235 int ret = M_OK;
236 if (self->is_Java_thread()) {
237 JavaThread* jt = (JavaThread*) self;
238 // Transition to VM so we can check interrupt state
239 ThreadInVMfromNative tivm(jt);
240 if (jt->is_interrupted(true)) {
241 ret = M_INTERRUPTED;
242 } else {
243 ThreadBlockInVM tbivm(jt);
244 jt->set_suspend_equivalent();
245 if (millis <= 0) {
246 self->_ParkEvent->park();
247 } else {
248 self->_ParkEvent->park(millis);
249 }
250 // Return to VM before post-check of interrupt state
251 }
252 if (jt->is_interrupted(true)) {
253 ret = M_INTERRUPTED;
254 }
255 } else {
256 if (millis <= 0) {
257 self->_ParkEvent->park();
258 } else {
259 self->_ParkEvent->park(millis);
260 }
261 }
262
263 dequeue_waiter(node);
264
265 simple_enter(self);
266 guarantee(_owner == self, "invariant");
267 guarantee(_recursions == 0, "invariant");
268
269 return ret;
270 }
271
272 void JvmtiRawMonitor::simple_notify(Thread* self, bool all) {
273 guarantee(_owner == self, "invariant");
274 if (_wait_set == NULL) {
275 return;
276 }
277
278 // We have two options:
279 // A. Transfer the threads from the _wait_set to the _entry_list
280 // B. Remove the thread from the _wait_set and unpark() it.
281 //
282 // We use (B), which is crude and results in lots of futile
283 // context switching. In particular (B) induces lots of contention.
284
285 ParkEvent* ev = NULL; // consider using a small auto array ...
286 RawMonitor_lock->lock_without_safepoint_check();
287 for (;;) {
288 QNode* w = _wait_set;
289 if (w == NULL) break;
290 _wait_set = w->_next;
291 if (ev != NULL) {
292 ev->unpark();
293 ev = NULL;
294 }
295 ev = w->_event;
296 OrderAccess::loadstore();
297 w->_t_state = QNode::TS_RUN;
298 OrderAccess::storeload();
299 if (!all) {
300 break;
301 }
302 }
303 RawMonitor_lock->unlock();
304 if (ev != NULL) {
305 ev->unpark();
306 }
307 return;
308 }
309
310 // Any JavaThread will enter here with state _thread_blocked
311 void JvmtiRawMonitor::raw_enter(Thread* self) {
312 void* contended;
313 JavaThread* jt = NULL;
314 // don't enter raw monitor if thread is being externally suspended, it will
315 // surprise the suspender if a "suspended" thread can still enter monitor
316 if (self->is_Java_thread()) {
317 jt = (JavaThread*)self;
318 jt->SR_lock()->lock_without_safepoint_check();
319 while (jt->is_external_suspend()) {
320 jt->SR_lock()->unlock();
321 jt->java_suspend_self();
322 jt->SR_lock()->lock_without_safepoint_check();
323 }
324 // guarded by SR_lock to avoid racing with new external suspend requests.
325 contended = Atomic::cmpxchg(&_owner, (Thread*)NULL, jt);
326 jt->SR_lock()->unlock();
327 } else {
328 contended = Atomic::cmpxchg(&_owner, (Thread*)NULL, self);
329 }
330
331 if (contended == self) {
332 _recursions++;
333 return;
334 }
335
336 if (contended == NULL) {
337 guarantee(_owner == self, "invariant");
338 guarantee(_recursions == 0, "invariant");
339 return;
340 }
341
342 self->set_current_pending_raw_monitor(this);
343
344 if (!self->is_Java_thread()) {
345 simple_enter(self);
346 } else {
347 guarantee(jt->thread_state() == _thread_blocked, "invariant");
348 for (;;) {
349 jt->set_suspend_equivalent();
350 // cleared by handle_special_suspend_equivalent_condition() or
351 // java_suspend_self()
352 simple_enter(jt);
353
354 // were we externally suspended while we were waiting?
355 if (!jt->handle_special_suspend_equivalent_condition()) {
356 break;
357 }
358
359 // This thread was externally suspended
360 // We have reentered the contended monitor, but while we were
361 // waiting another thread suspended us. We don't want to reenter
362 // the monitor while suspended because that would surprise the
363 // thread that suspended us.
364 //
365 // Drop the lock
366 simple_exit(jt);
367
368 jt->java_suspend_self();
369 }
370 }
371
372 self->set_current_pending_raw_monitor(NULL);
373
374 guarantee(_owner == self, "invariant");
375 guarantee(_recursions == 0, "invariant");
376 }
377
378 int JvmtiRawMonitor::raw_exit(Thread* self) {
379 if (self != _owner) {
380 return M_ILLEGAL_MONITOR_STATE;
381 }
382 if (_recursions > 0) {
383 _recursions--;
384 } else {
385 simple_exit(self);
386 }
387
388 return M_OK;
389 }
390
391 int JvmtiRawMonitor::raw_wait(jlong millis, Thread* self) {
392 if (self != _owner) {
393 return M_ILLEGAL_MONITOR_STATE;
394 }
395
396 int ret = M_OK;
397
398 // To avoid spurious wakeups we reset the parkevent. This is strictly optional.
399 // The caller must be able to tolerate spurious returns from raw_wait().
400 self->_ParkEvent->reset();
401 OrderAccess::fence();
402
403 intptr_t save = _recursions;
404 _recursions = 0;
405 _waiters++;
406 ret = simple_wait(self, millis);
407 _recursions = save;
408 _waiters--;
409
410 guarantee(self == _owner, "invariant");
411
412 if (self->is_Java_thread()) {
413 JavaThread* jt = (JavaThread*)self;
414 for (;;) {
415 jt->set_suspend_equivalent();
416 if (!jt->handle_special_suspend_equivalent_condition()) {
417 break;
418 } else {
419 // We've been suspended whilst waiting and so we have to
420 // relinquish the raw monitor until we are resumed. Of course
421 // after reacquiring we have to re-check for suspension again.
422 // Suspension requires we are _thread_blocked, and we also have to
423 // recheck for being interrupted.
424 simple_exit(jt);
425 {
426 ThreadInVMfromNative tivm(jt);
427 {
428 ThreadBlockInVM tbivm(jt);
429 jt->java_suspend_self();
430 }
431 if (jt->is_interrupted(true)) {
432 ret = M_INTERRUPTED;
433 }
434 }
435 simple_enter(jt);
436 }
437 }
438 guarantee(jt == _owner, "invariant");
439 } else {
440 assert(ret != M_INTERRUPTED, "Only JavaThreads can be interrupted");
441 }
442
443 return ret;
444 }
445
446 int JvmtiRawMonitor::raw_notify(Thread* self) {
447 if (self != _owner) {
448 return M_ILLEGAL_MONITOR_STATE;
449 }
450 simple_notify(self, false);
451 return M_OK;
452 }
453
454 int JvmtiRawMonitor::raw_notifyAll(Thread* self) {
455 if (self != _owner) {
456 return M_ILLEGAL_MONITOR_STATE;
457 }
458 simple_notify(self, true);
459 return M_OK;
460 }