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