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