Tue, 16 Aug 2016 12:48:43 -0700
Merge
1 /*
2 * Copyright (c) 2003, 2012, 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 */
25 #include "precompiled.hpp"
26 #include "prims/jvmtiRawMonitor.hpp"
27 #include "runtime/interfaceSupport.hpp"
28 #include "runtime/orderAccess.inline.hpp"
29 #include "runtime/thread.inline.hpp"
31 GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiRawMonitor*>(1,true);
33 void JvmtiPendingMonitors::transition_raw_monitors() {
34 assert((Threads::number_of_threads()==1),
35 "Java thread has not created yet or more than one java thread \
36 is running. Raw monitor transition will not work");
37 JavaThread *current_java_thread = JavaThread::current();
38 assert(current_java_thread->thread_state() == _thread_in_vm, "Must be in vm");
39 {
40 ThreadBlockInVM __tbivm(current_java_thread);
41 for(int i=0; i< count(); i++) {
42 JvmtiRawMonitor *rmonitor = monitors()->at(i);
43 int r = rmonitor->raw_enter(current_java_thread);
44 assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked");
45 }
46 }
47 // pending monitors are converted to real monitor so delete them all.
48 dispose();
49 }
51 //
52 // class JvmtiRawMonitor
53 //
55 JvmtiRawMonitor::JvmtiRawMonitor(const char *name) {
56 #ifdef ASSERT
57 _name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtInternal), name);
58 #else
59 _name = NULL;
60 #endif
61 _magic = JVMTI_RM_MAGIC;
62 }
64 JvmtiRawMonitor::~JvmtiRawMonitor() {
65 #ifdef ASSERT
66 FreeHeap(_name);
67 #endif
68 _magic = 0;
69 }
72 bool
73 JvmtiRawMonitor::is_valid() {
74 int value = 0;
76 // This object might not be a JvmtiRawMonitor so we can't assume
77 // the _magic field is properly aligned. Get the value in a safe
78 // way and then check against JVMTI_RM_MAGIC.
80 switch (sizeof(_magic)) {
81 case 2:
82 value = Bytes::get_native_u2((address)&_magic);
83 break;
85 case 4:
86 value = Bytes::get_native_u4((address)&_magic);
87 break;
89 case 8:
90 value = Bytes::get_native_u8((address)&_magic);
91 break;
93 default:
94 guarantee(false, "_magic field is an unexpected size");
95 }
97 return value == JVMTI_RM_MAGIC;
98 }
100 // -------------------------------------------------------------------------
101 // The raw monitor subsystem is entirely distinct from normal
102 // java-synchronization or jni-synchronization. raw monitors are not
103 // associated with objects. They can be implemented in any manner
104 // that makes sense. The original implementors decided to piggy-back
105 // the raw-monitor implementation on the existing Java objectMonitor mechanism.
106 // This flaw needs to fixed. We should reimplement raw monitors as sui-generis.
107 // Specifically, we should not implement raw monitors via java monitors.
108 // Time permitting, we should disentangle and deconvolve the two implementations
109 // and move the resulting raw monitor implementation over to the JVMTI directories.
110 // Ideally, the raw monitor implementation would be built on top of
111 // park-unpark and nothing else.
112 //
113 // raw monitors are used mainly by JVMTI
114 // The raw monitor implementation borrows the ObjectMonitor structure,
115 // but the operators are degenerate and extremely simple.
116 //
117 // Mixed use of a single objectMonitor instance -- as both a raw monitor
118 // and a normal java monitor -- is not permissible.
119 //
120 // Note that we use the single RawMonitor_lock to protect queue operations for
121 // _all_ raw monitors. This is a scalability impediment, but since raw monitor usage
122 // is deprecated and rare, this is not of concern. The RawMonitor_lock can not
123 // be held indefinitely. The critical sections must be short and bounded.
124 //
125 // -------------------------------------------------------------------------
127 int JvmtiRawMonitor::SimpleEnter (Thread * Self) {
128 for (;;) {
129 if (Atomic::cmpxchg_ptr (Self, &_owner, NULL) == NULL) {
130 return OS_OK ;
131 }
133 ObjectWaiter Node (Self) ;
134 Self->_ParkEvent->reset() ; // strictly optional
135 Node.TState = ObjectWaiter::TS_ENTER ;
137 RawMonitor_lock->lock_without_safepoint_check() ;
138 Node._next = _EntryList ;
139 _EntryList = &Node ;
140 OrderAccess::fence() ;
141 if (_owner == NULL && Atomic::cmpxchg_ptr (Self, &_owner, NULL) == NULL) {
142 _EntryList = Node._next ;
143 RawMonitor_lock->unlock() ;
144 return OS_OK ;
145 }
146 RawMonitor_lock->unlock() ;
147 while (Node.TState == ObjectWaiter::TS_ENTER) {
148 Self->_ParkEvent->park() ;
149 }
150 }
151 }
153 int JvmtiRawMonitor::SimpleExit (Thread * Self) {
154 guarantee (_owner == Self, "invariant") ;
155 OrderAccess::release_store_ptr (&_owner, NULL) ;
156 OrderAccess::fence() ;
157 if (_EntryList == NULL) return OS_OK ;
158 ObjectWaiter * w ;
160 RawMonitor_lock->lock_without_safepoint_check() ;
161 w = _EntryList ;
162 if (w != NULL) {
163 _EntryList = w->_next ;
164 }
165 RawMonitor_lock->unlock() ;
166 if (w != NULL) {
167 guarantee (w ->TState == ObjectWaiter::TS_ENTER, "invariant") ;
168 ParkEvent * ev = w->_event ;
169 w->TState = ObjectWaiter::TS_RUN ;
170 OrderAccess::fence() ;
171 ev->unpark() ;
172 }
173 return OS_OK ;
174 }
176 int JvmtiRawMonitor::SimpleWait (Thread * Self, jlong millis) {
177 guarantee (_owner == Self , "invariant") ;
178 guarantee (_recursions == 0, "invariant") ;
180 ObjectWaiter Node (Self) ;
181 Node._notified = 0 ;
182 Node.TState = ObjectWaiter::TS_WAIT ;
184 RawMonitor_lock->lock_without_safepoint_check() ;
185 Node._next = _WaitSet ;
186 _WaitSet = &Node ;
187 RawMonitor_lock->unlock() ;
189 SimpleExit (Self) ;
190 guarantee (_owner != Self, "invariant") ;
192 int ret = OS_OK ;
193 if (millis <= 0) {
194 Self->_ParkEvent->park();
195 } else {
196 ret = Self->_ParkEvent->park(millis);
197 }
199 // If thread still resides on the waitset then unlink it.
200 // Double-checked locking -- the usage is safe in this context
201 // as we TState is volatile and the lock-unlock operators are
202 // serializing (barrier-equivalent).
204 if (Node.TState == ObjectWaiter::TS_WAIT) {
205 RawMonitor_lock->lock_without_safepoint_check() ;
206 if (Node.TState == ObjectWaiter::TS_WAIT) {
207 // Simple O(n) unlink, but performance isn't critical here.
208 ObjectWaiter * p ;
209 ObjectWaiter * q = NULL ;
210 for (p = _WaitSet ; p != &Node; p = p->_next) {
211 q = p ;
212 }
213 guarantee (p == &Node, "invariant") ;
214 if (q == NULL) {
215 guarantee (p == _WaitSet, "invariant") ;
216 _WaitSet = p->_next ;
217 } else {
218 guarantee (p == q->_next, "invariant") ;
219 q->_next = p->_next ;
220 }
221 Node.TState = ObjectWaiter::TS_RUN ;
222 }
223 RawMonitor_lock->unlock() ;
224 }
226 guarantee (Node.TState == ObjectWaiter::TS_RUN, "invariant") ;
227 SimpleEnter (Self) ;
229 guarantee (_owner == Self, "invariant") ;
230 guarantee (_recursions == 0, "invariant") ;
231 return ret ;
232 }
234 int JvmtiRawMonitor::SimpleNotify (Thread * Self, bool All) {
235 guarantee (_owner == Self, "invariant") ;
236 if (_WaitSet == NULL) return OS_OK ;
238 // We have two options:
239 // A. Transfer the threads from the WaitSet to the EntryList
240 // B. Remove the thread from the WaitSet and unpark() it.
241 //
242 // We use (B), which is crude and results in lots of futile
243 // context switching. In particular (B) induces lots of contention.
245 ParkEvent * ev = NULL ; // consider using a small auto array ...
246 RawMonitor_lock->lock_without_safepoint_check() ;
247 for (;;) {
248 ObjectWaiter * w = _WaitSet ;
249 if (w == NULL) break ;
250 _WaitSet = w->_next ;
251 if (ev != NULL) { ev->unpark(); ev = NULL; }
252 ev = w->_event ;
253 OrderAccess::loadstore() ;
254 w->TState = ObjectWaiter::TS_RUN ;
255 OrderAccess::storeload();
256 if (!All) break ;
257 }
258 RawMonitor_lock->unlock() ;
259 if (ev != NULL) ev->unpark();
260 return OS_OK ;
261 }
263 // Any JavaThread will enter here with state _thread_blocked
264 int JvmtiRawMonitor::raw_enter(TRAPS) {
265 TEVENT (raw_enter) ;
266 void * Contended ;
268 // don't enter raw monitor if thread is being externally suspended, it will
269 // surprise the suspender if a "suspended" thread can still enter monitor
270 JavaThread * jt = (JavaThread *)THREAD;
271 if (THREAD->is_Java_thread()) {
272 jt->SR_lock()->lock_without_safepoint_check();
273 while (jt->is_external_suspend()) {
274 jt->SR_lock()->unlock();
275 jt->java_suspend_self();
276 jt->SR_lock()->lock_without_safepoint_check();
277 }
278 // guarded by SR_lock to avoid racing with new external suspend requests.
279 Contended = Atomic::cmpxchg_ptr (THREAD, &_owner, NULL) ;
280 jt->SR_lock()->unlock();
281 } else {
282 Contended = Atomic::cmpxchg_ptr (THREAD, &_owner, NULL) ;
283 }
285 if (Contended == THREAD) {
286 _recursions ++ ;
287 return OM_OK ;
288 }
290 if (Contended == NULL) {
291 guarantee (_owner == THREAD, "invariant") ;
292 guarantee (_recursions == 0, "invariant") ;
293 return OM_OK ;
294 }
296 THREAD->set_current_pending_monitor(this);
298 if (!THREAD->is_Java_thread()) {
299 // No other non-Java threads besides VM thread would acquire
300 // a raw monitor.
301 assert(THREAD->is_VM_thread(), "must be VM thread");
302 SimpleEnter (THREAD) ;
303 } else {
304 guarantee (jt->thread_state() == _thread_blocked, "invariant") ;
305 for (;;) {
306 jt->set_suspend_equivalent();
307 // cleared by handle_special_suspend_equivalent_condition() or
308 // java_suspend_self()
309 SimpleEnter (THREAD) ;
311 // were we externally suspended while we were waiting?
312 if (!jt->handle_special_suspend_equivalent_condition()) break ;
314 // This thread was externally suspended
315 //
316 // This logic isn't needed for JVMTI raw monitors,
317 // but doesn't hurt just in case the suspend rules change. This
318 // logic is needed for the JvmtiRawMonitor.wait() reentry phase.
319 // We have reentered the contended monitor, but while we were
320 // waiting another thread suspended us. We don't want to reenter
321 // the monitor while suspended because that would surprise the
322 // thread that suspended us.
323 //
324 // Drop the lock -
325 SimpleExit (THREAD) ;
327 jt->java_suspend_self();
328 }
330 assert(_owner == THREAD, "Fatal error with monitor owner!");
331 assert(_recursions == 0, "Fatal error with monitor recursions!");
332 }
334 THREAD->set_current_pending_monitor(NULL);
335 guarantee (_recursions == 0, "invariant") ;
336 return OM_OK;
337 }
339 // Used mainly for JVMTI raw monitor implementation
340 // Also used for JvmtiRawMonitor::wait().
341 int JvmtiRawMonitor::raw_exit(TRAPS) {
342 TEVENT (raw_exit) ;
343 if (THREAD != _owner) {
344 return OM_ILLEGAL_MONITOR_STATE;
345 }
346 if (_recursions > 0) {
347 --_recursions ;
348 return OM_OK ;
349 }
351 void * List = _EntryList ;
352 SimpleExit (THREAD) ;
354 return OM_OK;
355 }
357 // Used for JVMTI raw monitor implementation.
358 // All JavaThreads will enter here with state _thread_blocked
360 int JvmtiRawMonitor::raw_wait(jlong millis, bool interruptible, TRAPS) {
361 TEVENT (raw_wait) ;
362 if (THREAD != _owner) {
363 return OM_ILLEGAL_MONITOR_STATE;
364 }
366 // To avoid spurious wakeups we reset the parkevent -- This is strictly optional.
367 // The caller must be able to tolerate spurious returns from raw_wait().
368 THREAD->_ParkEvent->reset() ;
369 OrderAccess::fence() ;
371 // check interrupt event
372 if (interruptible && Thread::is_interrupted(THREAD, true)) {
373 return OM_INTERRUPTED;
374 }
376 intptr_t save = _recursions ;
377 _recursions = 0 ;
378 _waiters ++ ;
379 if (THREAD->is_Java_thread()) {
380 guarantee (((JavaThread *) THREAD)->thread_state() == _thread_blocked, "invariant") ;
381 ((JavaThread *)THREAD)->set_suspend_equivalent();
382 }
383 int rv = SimpleWait (THREAD, millis) ;
384 _recursions = save ;
385 _waiters -- ;
387 guarantee (THREAD == _owner, "invariant") ;
388 if (THREAD->is_Java_thread()) {
389 JavaThread * jSelf = (JavaThread *) THREAD ;
390 for (;;) {
391 if (!jSelf->handle_special_suspend_equivalent_condition()) break ;
392 SimpleExit (THREAD) ;
393 jSelf->java_suspend_self();
394 SimpleEnter (THREAD) ;
395 jSelf->set_suspend_equivalent() ;
396 }
397 }
398 guarantee (THREAD == _owner, "invariant") ;
400 if (interruptible && Thread::is_interrupted(THREAD, true)) {
401 return OM_INTERRUPTED;
402 }
403 return OM_OK ;
404 }
406 int JvmtiRawMonitor::raw_notify(TRAPS) {
407 TEVENT (raw_notify) ;
408 if (THREAD != _owner) {
409 return OM_ILLEGAL_MONITOR_STATE;
410 }
411 SimpleNotify (THREAD, false) ;
412 return OM_OK;
413 }
415 int JvmtiRawMonitor::raw_notifyAll(TRAPS) {
416 TEVENT (raw_notifyAll) ;
417 if (THREAD != _owner) {
418 return OM_ILLEGAL_MONITOR_STATE;
419 }
420 SimpleNotify (THREAD, true) ;
421 return OM_OK;
422 }