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