1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/prims/jvmtiRawMonitor.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,422 @@ 1.4 +/* 1.5 + * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "prims/jvmtiRawMonitor.hpp" 1.30 +#include "runtime/interfaceSupport.hpp" 1.31 +#include "runtime/thread.hpp" 1.32 + 1.33 +GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiRawMonitor*>(1,true); 1.34 + 1.35 +void JvmtiPendingMonitors::transition_raw_monitors() { 1.36 + assert((Threads::number_of_threads()==1), 1.37 + "Java thread has not created yet or more than one java thread \ 1.38 +is running. Raw monitor transition will not work"); 1.39 + JavaThread *current_java_thread = JavaThread::current(); 1.40 + assert(current_java_thread->thread_state() == _thread_in_vm, "Must be in vm"); 1.41 + { 1.42 + ThreadBlockInVM __tbivm(current_java_thread); 1.43 + for(int i=0; i< count(); i++) { 1.44 + JvmtiRawMonitor *rmonitor = monitors()->at(i); 1.45 + int r = rmonitor->raw_enter(current_java_thread); 1.46 + assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked"); 1.47 + } 1.48 + } 1.49 + // pending monitors are converted to real monitor so delete them all. 1.50 + dispose(); 1.51 +} 1.52 + 1.53 +// 1.54 +// class JvmtiRawMonitor 1.55 +// 1.56 + 1.57 +JvmtiRawMonitor::JvmtiRawMonitor(const char *name) { 1.58 +#ifdef ASSERT 1.59 + _name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtInternal), name); 1.60 +#else 1.61 + _name = NULL; 1.62 +#endif 1.63 + _magic = JVMTI_RM_MAGIC; 1.64 +} 1.65 + 1.66 +JvmtiRawMonitor::~JvmtiRawMonitor() { 1.67 +#ifdef ASSERT 1.68 + FreeHeap(_name); 1.69 +#endif 1.70 + _magic = 0; 1.71 +} 1.72 + 1.73 + 1.74 +bool 1.75 +JvmtiRawMonitor::is_valid() { 1.76 + int value = 0; 1.77 + 1.78 + // This object might not be a JvmtiRawMonitor so we can't assume 1.79 + // the _magic field is properly aligned. Get the value in a safe 1.80 + // way and then check against JVMTI_RM_MAGIC. 1.81 + 1.82 + switch (sizeof(_magic)) { 1.83 + case 2: 1.84 + value = Bytes::get_native_u2((address)&_magic); 1.85 + break; 1.86 + 1.87 + case 4: 1.88 + value = Bytes::get_native_u4((address)&_magic); 1.89 + break; 1.90 + 1.91 + case 8: 1.92 + value = Bytes::get_native_u8((address)&_magic); 1.93 + break; 1.94 + 1.95 + default: 1.96 + guarantee(false, "_magic field is an unexpected size"); 1.97 + } 1.98 + 1.99 + return value == JVMTI_RM_MAGIC; 1.100 +} 1.101 + 1.102 +// ------------------------------------------------------------------------- 1.103 +// The raw monitor subsystem is entirely distinct from normal 1.104 +// java-synchronization or jni-synchronization. raw monitors are not 1.105 +// associated with objects. They can be implemented in any manner 1.106 +// that makes sense. The original implementors decided to piggy-back 1.107 +// the raw-monitor implementation on the existing Java objectMonitor mechanism. 1.108 +// This flaw needs to fixed. We should reimplement raw monitors as sui-generis. 1.109 +// Specifically, we should not implement raw monitors via java monitors. 1.110 +// Time permitting, we should disentangle and deconvolve the two implementations 1.111 +// and move the resulting raw monitor implementation over to the JVMTI directories. 1.112 +// Ideally, the raw monitor implementation would be built on top of 1.113 +// park-unpark and nothing else. 1.114 +// 1.115 +// raw monitors are used mainly by JVMTI 1.116 +// The raw monitor implementation borrows the ObjectMonitor structure, 1.117 +// but the operators are degenerate and extremely simple. 1.118 +// 1.119 +// Mixed use of a single objectMonitor instance -- as both a raw monitor 1.120 +// and a normal java monitor -- is not permissible. 1.121 +// 1.122 +// Note that we use the single RawMonitor_lock to protect queue operations for 1.123 +// _all_ raw monitors. This is a scalability impediment, but since raw monitor usage 1.124 +// is deprecated and rare, this is not of concern. The RawMonitor_lock can not 1.125 +// be held indefinitely. The critical sections must be short and bounded. 1.126 +// 1.127 +// ------------------------------------------------------------------------- 1.128 + 1.129 +int JvmtiRawMonitor::SimpleEnter (Thread * Self) { 1.130 + for (;;) { 1.131 + if (Atomic::cmpxchg_ptr (Self, &_owner, NULL) == NULL) { 1.132 + return OS_OK ; 1.133 + } 1.134 + 1.135 + ObjectWaiter Node (Self) ; 1.136 + Self->_ParkEvent->reset() ; // strictly optional 1.137 + Node.TState = ObjectWaiter::TS_ENTER ; 1.138 + 1.139 + RawMonitor_lock->lock_without_safepoint_check() ; 1.140 + Node._next = _EntryList ; 1.141 + _EntryList = &Node ; 1.142 + OrderAccess::fence() ; 1.143 + if (_owner == NULL && Atomic::cmpxchg_ptr (Self, &_owner, NULL) == NULL) { 1.144 + _EntryList = Node._next ; 1.145 + RawMonitor_lock->unlock() ; 1.146 + return OS_OK ; 1.147 + } 1.148 + RawMonitor_lock->unlock() ; 1.149 + while (Node.TState == ObjectWaiter::TS_ENTER) { 1.150 + Self->_ParkEvent->park() ; 1.151 + } 1.152 + } 1.153 +} 1.154 + 1.155 +int JvmtiRawMonitor::SimpleExit (Thread * Self) { 1.156 + guarantee (_owner == Self, "invariant") ; 1.157 + OrderAccess::release_store_ptr (&_owner, NULL) ; 1.158 + OrderAccess::fence() ; 1.159 + if (_EntryList == NULL) return OS_OK ; 1.160 + ObjectWaiter * w ; 1.161 + 1.162 + RawMonitor_lock->lock_without_safepoint_check() ; 1.163 + w = _EntryList ; 1.164 + if (w != NULL) { 1.165 + _EntryList = w->_next ; 1.166 + } 1.167 + RawMonitor_lock->unlock() ; 1.168 + if (w != NULL) { 1.169 + guarantee (w ->TState == ObjectWaiter::TS_ENTER, "invariant") ; 1.170 + ParkEvent * ev = w->_event ; 1.171 + w->TState = ObjectWaiter::TS_RUN ; 1.172 + OrderAccess::fence() ; 1.173 + ev->unpark() ; 1.174 + } 1.175 + return OS_OK ; 1.176 +} 1.177 + 1.178 +int JvmtiRawMonitor::SimpleWait (Thread * Self, jlong millis) { 1.179 + guarantee (_owner == Self , "invariant") ; 1.180 + guarantee (_recursions == 0, "invariant") ; 1.181 + 1.182 + ObjectWaiter Node (Self) ; 1.183 + Node._notified = 0 ; 1.184 + Node.TState = ObjectWaiter::TS_WAIT ; 1.185 + 1.186 + RawMonitor_lock->lock_without_safepoint_check() ; 1.187 + Node._next = _WaitSet ; 1.188 + _WaitSet = &Node ; 1.189 + RawMonitor_lock->unlock() ; 1.190 + 1.191 + SimpleExit (Self) ; 1.192 + guarantee (_owner != Self, "invariant") ; 1.193 + 1.194 + int ret = OS_OK ; 1.195 + if (millis <= 0) { 1.196 + Self->_ParkEvent->park(); 1.197 + } else { 1.198 + ret = Self->_ParkEvent->park(millis); 1.199 + } 1.200 + 1.201 + // If thread still resides on the waitset then unlink it. 1.202 + // Double-checked locking -- the usage is safe in this context 1.203 + // as we TState is volatile and the lock-unlock operators are 1.204 + // serializing (barrier-equivalent). 1.205 + 1.206 + if (Node.TState == ObjectWaiter::TS_WAIT) { 1.207 + RawMonitor_lock->lock_without_safepoint_check() ; 1.208 + if (Node.TState == ObjectWaiter::TS_WAIT) { 1.209 + // Simple O(n) unlink, but performance isn't critical here. 1.210 + ObjectWaiter * p ; 1.211 + ObjectWaiter * q = NULL ; 1.212 + for (p = _WaitSet ; p != &Node; p = p->_next) { 1.213 + q = p ; 1.214 + } 1.215 + guarantee (p == &Node, "invariant") ; 1.216 + if (q == NULL) { 1.217 + guarantee (p == _WaitSet, "invariant") ; 1.218 + _WaitSet = p->_next ; 1.219 + } else { 1.220 + guarantee (p == q->_next, "invariant") ; 1.221 + q->_next = p->_next ; 1.222 + } 1.223 + Node.TState = ObjectWaiter::TS_RUN ; 1.224 + } 1.225 + RawMonitor_lock->unlock() ; 1.226 + } 1.227 + 1.228 + guarantee (Node.TState == ObjectWaiter::TS_RUN, "invariant") ; 1.229 + SimpleEnter (Self) ; 1.230 + 1.231 + guarantee (_owner == Self, "invariant") ; 1.232 + guarantee (_recursions == 0, "invariant") ; 1.233 + return ret ; 1.234 +} 1.235 + 1.236 +int JvmtiRawMonitor::SimpleNotify (Thread * Self, bool All) { 1.237 + guarantee (_owner == Self, "invariant") ; 1.238 + if (_WaitSet == NULL) return OS_OK ; 1.239 + 1.240 + // We have two options: 1.241 + // A. Transfer the threads from the WaitSet to the EntryList 1.242 + // B. Remove the thread from the WaitSet and unpark() it. 1.243 + // 1.244 + // We use (B), which is crude and results in lots of futile 1.245 + // context switching. In particular (B) induces lots of contention. 1.246 + 1.247 + ParkEvent * ev = NULL ; // consider using a small auto array ... 1.248 + RawMonitor_lock->lock_without_safepoint_check() ; 1.249 + for (;;) { 1.250 + ObjectWaiter * w = _WaitSet ; 1.251 + if (w == NULL) break ; 1.252 + _WaitSet = w->_next ; 1.253 + if (ev != NULL) { ev->unpark(); ev = NULL; } 1.254 + ev = w->_event ; 1.255 + OrderAccess::loadstore() ; 1.256 + w->TState = ObjectWaiter::TS_RUN ; 1.257 + OrderAccess::storeload(); 1.258 + if (!All) break ; 1.259 + } 1.260 + RawMonitor_lock->unlock() ; 1.261 + if (ev != NULL) ev->unpark(); 1.262 + return OS_OK ; 1.263 +} 1.264 + 1.265 +// Any JavaThread will enter here with state _thread_blocked 1.266 +int JvmtiRawMonitor::raw_enter(TRAPS) { 1.267 + TEVENT (raw_enter) ; 1.268 + void * Contended ; 1.269 + 1.270 + // don't enter raw monitor if thread is being externally suspended, it will 1.271 + // surprise the suspender if a "suspended" thread can still enter monitor 1.272 + JavaThread * jt = (JavaThread *)THREAD; 1.273 + if (THREAD->is_Java_thread()) { 1.274 + jt->SR_lock()->lock_without_safepoint_check(); 1.275 + while (jt->is_external_suspend()) { 1.276 + jt->SR_lock()->unlock(); 1.277 + jt->java_suspend_self(); 1.278 + jt->SR_lock()->lock_without_safepoint_check(); 1.279 + } 1.280 + // guarded by SR_lock to avoid racing with new external suspend requests. 1.281 + Contended = Atomic::cmpxchg_ptr (THREAD, &_owner, NULL) ; 1.282 + jt->SR_lock()->unlock(); 1.283 + } else { 1.284 + Contended = Atomic::cmpxchg_ptr (THREAD, &_owner, NULL) ; 1.285 + } 1.286 + 1.287 + if (Contended == THREAD) { 1.288 + _recursions ++ ; 1.289 + return OM_OK ; 1.290 + } 1.291 + 1.292 + if (Contended == NULL) { 1.293 + guarantee (_owner == THREAD, "invariant") ; 1.294 + guarantee (_recursions == 0, "invariant") ; 1.295 + return OM_OK ; 1.296 + } 1.297 + 1.298 + THREAD->set_current_pending_monitor(this); 1.299 + 1.300 + if (!THREAD->is_Java_thread()) { 1.301 + // No other non-Java threads besides VM thread would acquire 1.302 + // a raw monitor. 1.303 + assert(THREAD->is_VM_thread(), "must be VM thread"); 1.304 + SimpleEnter (THREAD) ; 1.305 + } else { 1.306 + guarantee (jt->thread_state() == _thread_blocked, "invariant") ; 1.307 + for (;;) { 1.308 + jt->set_suspend_equivalent(); 1.309 + // cleared by handle_special_suspend_equivalent_condition() or 1.310 + // java_suspend_self() 1.311 + SimpleEnter (THREAD) ; 1.312 + 1.313 + // were we externally suspended while we were waiting? 1.314 + if (!jt->handle_special_suspend_equivalent_condition()) break ; 1.315 + 1.316 + // This thread was externally suspended 1.317 + // 1.318 + // This logic isn't needed for JVMTI raw monitors, 1.319 + // but doesn't hurt just in case the suspend rules change. This 1.320 + // logic is needed for the JvmtiRawMonitor.wait() reentry phase. 1.321 + // We have reentered the contended monitor, but while we were 1.322 + // waiting another thread suspended us. We don't want to reenter 1.323 + // the monitor while suspended because that would surprise the 1.324 + // thread that suspended us. 1.325 + // 1.326 + // Drop the lock - 1.327 + SimpleExit (THREAD) ; 1.328 + 1.329 + jt->java_suspend_self(); 1.330 + } 1.331 + 1.332 + assert(_owner == THREAD, "Fatal error with monitor owner!"); 1.333 + assert(_recursions == 0, "Fatal error with monitor recursions!"); 1.334 + } 1.335 + 1.336 + THREAD->set_current_pending_monitor(NULL); 1.337 + guarantee (_recursions == 0, "invariant") ; 1.338 + return OM_OK; 1.339 +} 1.340 + 1.341 +// Used mainly for JVMTI raw monitor implementation 1.342 +// Also used for JvmtiRawMonitor::wait(). 1.343 +int JvmtiRawMonitor::raw_exit(TRAPS) { 1.344 + TEVENT (raw_exit) ; 1.345 + if (THREAD != _owner) { 1.346 + return OM_ILLEGAL_MONITOR_STATE; 1.347 + } 1.348 + if (_recursions > 0) { 1.349 + --_recursions ; 1.350 + return OM_OK ; 1.351 + } 1.352 + 1.353 + void * List = _EntryList ; 1.354 + SimpleExit (THREAD) ; 1.355 + 1.356 + return OM_OK; 1.357 +} 1.358 + 1.359 +// Used for JVMTI raw monitor implementation. 1.360 +// All JavaThreads will enter here with state _thread_blocked 1.361 + 1.362 +int JvmtiRawMonitor::raw_wait(jlong millis, bool interruptible, TRAPS) { 1.363 + TEVENT (raw_wait) ; 1.364 + if (THREAD != _owner) { 1.365 + return OM_ILLEGAL_MONITOR_STATE; 1.366 + } 1.367 + 1.368 + // To avoid spurious wakeups we reset the parkevent -- This is strictly optional. 1.369 + // The caller must be able to tolerate spurious returns from raw_wait(). 1.370 + THREAD->_ParkEvent->reset() ; 1.371 + OrderAccess::fence() ; 1.372 + 1.373 + // check interrupt event 1.374 + if (interruptible && Thread::is_interrupted(THREAD, true)) { 1.375 + return OM_INTERRUPTED; 1.376 + } 1.377 + 1.378 + intptr_t save = _recursions ; 1.379 + _recursions = 0 ; 1.380 + _waiters ++ ; 1.381 + if (THREAD->is_Java_thread()) { 1.382 + guarantee (((JavaThread *) THREAD)->thread_state() == _thread_blocked, "invariant") ; 1.383 + ((JavaThread *)THREAD)->set_suspend_equivalent(); 1.384 + } 1.385 + int rv = SimpleWait (THREAD, millis) ; 1.386 + _recursions = save ; 1.387 + _waiters -- ; 1.388 + 1.389 + guarantee (THREAD == _owner, "invariant") ; 1.390 + if (THREAD->is_Java_thread()) { 1.391 + JavaThread * jSelf = (JavaThread *) THREAD ; 1.392 + for (;;) { 1.393 + if (!jSelf->handle_special_suspend_equivalent_condition()) break ; 1.394 + SimpleExit (THREAD) ; 1.395 + jSelf->java_suspend_self(); 1.396 + SimpleEnter (THREAD) ; 1.397 + jSelf->set_suspend_equivalent() ; 1.398 + } 1.399 + } 1.400 + guarantee (THREAD == _owner, "invariant") ; 1.401 + 1.402 + if (interruptible && Thread::is_interrupted(THREAD, true)) { 1.403 + return OM_INTERRUPTED; 1.404 + } 1.405 + return OM_OK ; 1.406 +} 1.407 + 1.408 +int JvmtiRawMonitor::raw_notify(TRAPS) { 1.409 + TEVENT (raw_notify) ; 1.410 + if (THREAD != _owner) { 1.411 + return OM_ILLEGAL_MONITOR_STATE; 1.412 + } 1.413 + SimpleNotify (THREAD, false) ; 1.414 + return OM_OK; 1.415 +} 1.416 + 1.417 +int JvmtiRawMonitor::raw_notifyAll(TRAPS) { 1.418 + TEVENT (raw_notifyAll) ; 1.419 + if (THREAD != _owner) { 1.420 + return OM_ILLEGAL_MONITOR_STATE; 1.421 + } 1.422 + SimpleNotify (THREAD, true) ; 1.423 + return OM_OK; 1.424 +} 1.425 +