1 /* 2 * Copyright (c) 2003, 2018, 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.inline.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 ParkEvent * ev = w->_event ; 171 w->TState = ObjectWaiter::TS_RUN ; 172 OrderAccess::fence() ; 173 ev->unpark() ; 174 } 175 return OS_OK ; 176 } 177 178 int JvmtiRawMonitor::SimpleWait (Thread * Self, jlong millis) { 179 guarantee (_owner == Self , "invariant") ; 180 guarantee (_recursions == 0, "invariant") ; 181 182 ObjectWaiter Node (Self) ; 183 Node._notified = 0 ; 184 Node.TState = ObjectWaiter::TS_WAIT ; 185 186 RawMonitor_lock->lock_without_safepoint_check() ; 187 Node._next = _WaitSet ; 188 _WaitSet = &Node ; 189 RawMonitor_lock->unlock() ; 190 191 SimpleExit (Self) ; 192 guarantee (_owner != Self, "invariant") ; 193 194 int ret = OS_OK ; 195 if (millis <= 0) { 196 Self->_ParkEvent->park(); 197 } else { 198 ret = Self->_ParkEvent->park(millis); 199 } 200 201 // If thread still resides on the waitset then unlink it. 202 // Double-checked locking -- the usage is safe in this context 203 // as we TState is volatile and the lock-unlock operators are 204 // serializing (barrier-equivalent). 205 206 if (Node.TState == ObjectWaiter::TS_WAIT) { 207 RawMonitor_lock->lock_without_safepoint_check() ; 208 if (Node.TState == ObjectWaiter::TS_WAIT) { 209 // Simple O(n) unlink, but performance isn't critical here. 210 ObjectWaiter * p ; 211 ObjectWaiter * q = NULL ; 212 for (p = _WaitSet ; p != &Node; p = p->_next) { 213 q = p ; 214 } 215 guarantee (p == &Node, "invariant") ; 216 if (q == NULL) { 217 guarantee (p == _WaitSet, "invariant") ; 218 _WaitSet = p->_next ; 219 } else { 220 guarantee (p == q->_next, "invariant") ; 221 q->_next = p->_next ; 222 } 223 Node.TState = ObjectWaiter::TS_RUN ; 224 } 225 RawMonitor_lock->unlock() ; 226 } 227 228 guarantee (Node.TState == ObjectWaiter::TS_RUN, "invariant") ; 229 SimpleEnter (Self) ; 230 231 guarantee (_owner == Self, "invariant") ; 232 guarantee (_recursions == 0, "invariant") ; 233 return ret ; 234 } 235 236 int JvmtiRawMonitor::SimpleNotify (Thread * Self, bool All) { 237 guarantee (_owner == Self, "invariant") ; 238 if (_WaitSet == NULL) return OS_OK ; 239 240 // We have two options: 241 // A. Transfer the threads from the WaitSet to the EntryList 242 // B. Remove the thread from the WaitSet and unpark() it. 243 // 244 // We use (B), which is crude and results in lots of futile 245 // context switching. In particular (B) induces lots of contention. 246 247 ParkEvent * ev = NULL ; // consider using a small auto array ... 248 RawMonitor_lock->lock_without_safepoint_check() ; 249 for (;;) { 250 ObjectWaiter * w = _WaitSet ; 251 if (w == NULL) break ; 252 _WaitSet = w->_next ; 253 if (ev != NULL) { ev->unpark(); ev = NULL; } 254 ev = w->_event ; 255 OrderAccess::loadstore() ; 256 w->TState = ObjectWaiter::TS_RUN ; 257 OrderAccess::storeload(); 258 if (!All) break ; 259 } 260 RawMonitor_lock->unlock() ; 261 if (ev != NULL) ev->unpark(); 262 return OS_OK ; 263 } 264 265 // Any JavaThread will enter here with state _thread_blocked 266 int JvmtiRawMonitor::raw_enter(TRAPS) { 267 TEVENT (raw_enter) ; 268 void * Contended ; 269 270 // don't enter raw monitor if thread is being externally suspended, it will 271 // surprise the suspender if a "suspended" thread can still enter monitor 272 JavaThread * jt = (JavaThread *)THREAD; 273 if (THREAD->is_Java_thread()) { 274 jt->SR_lock()->lock_without_safepoint_check(); 275 while (jt->is_external_suspend()) { 276 jt->SR_lock()->unlock(); 277 jt->java_suspend_self(); 278 jt->SR_lock()->lock_without_safepoint_check(); 279 } 280 // guarded by SR_lock to avoid racing with new external suspend requests. 281 Contended = Atomic::cmpxchg(THREAD, &_owner, (void*)NULL); 282 jt->SR_lock()->unlock(); 283 } else { 284 Contended = Atomic::cmpxchg(THREAD, &_owner, (void*)NULL); 285 } 286 287 if (Contended == THREAD) { 288 _recursions ++ ; 289 return OM_OK ; 290 } 291 292 if (Contended == NULL) { 293 guarantee (_owner == THREAD, "invariant") ; 294 guarantee (_recursions == 0, "invariant") ; 295 return OM_OK ; 296 } 297 298 THREAD->set_current_pending_monitor(this); 299 300 if (!THREAD->is_Java_thread()) { 301 // No other non-Java threads besides VM thread would acquire 302 // a raw monitor. 303 assert(THREAD->is_VM_thread(), "must be VM thread"); 304 SimpleEnter (THREAD) ; 305 } else { 306 guarantee (jt->thread_state() == _thread_blocked, "invariant") ; 307 for (;;) { 308 jt->set_suspend_equivalent(); 309 // cleared by handle_special_suspend_equivalent_condition() or 310 // java_suspend_self() 311 SimpleEnter (THREAD) ; 312 313 // were we externally suspended while we were waiting? 314 if (!jt->handle_special_suspend_equivalent_condition()) break ; 315 316 // This thread was externally suspended 317 // 318 // This logic isn't needed for JVMTI raw monitors, 319 // but doesn't hurt just in case the suspend rules change. This 320 // logic is needed for the JvmtiRawMonitor.wait() reentry phase. 321 // We have reentered the contended monitor, but while we were 322 // waiting another thread suspended us. We don't want to reenter 323 // the monitor while suspended because that would surprise the 324 // thread that suspended us. 325 // 326 // Drop the lock - 327 SimpleExit (THREAD) ; 328 329 jt->java_suspend_self(); 330 } 331 332 assert(_owner == THREAD, "Fatal error with monitor owner!"); 333 assert(_recursions == 0, "Fatal error with monitor recursions!"); 334 } 335 336 THREAD->set_current_pending_monitor(NULL); 337 guarantee (_recursions == 0, "invariant") ; 338 return OM_OK; 339 } 340 341 // Used mainly for JVMTI raw monitor implementation 342 // Also used for JvmtiRawMonitor::wait(). 343 int JvmtiRawMonitor::raw_exit(TRAPS) { 344 TEVENT (raw_exit) ; 345 if (THREAD != _owner) { 346 return OM_ILLEGAL_MONITOR_STATE; 347 } 348 if (_recursions > 0) { 349 --_recursions ; 350 return OM_OK ; 351 } 352 353 void * List = _EntryList ; 354 SimpleExit (THREAD) ; 355 356 return OM_OK; 357 } 358 359 // Used for JVMTI raw monitor implementation. 360 // All JavaThreads will enter here with state _thread_blocked 361 362 int JvmtiRawMonitor::raw_wait(jlong millis, bool interruptible, TRAPS) { 363 TEVENT (raw_wait) ; 364 if (THREAD != _owner) { 365 return OM_ILLEGAL_MONITOR_STATE; 366 } 367 368 // To avoid spurious wakeups we reset the parkevent -- This is strictly optional. 369 // The caller must be able to tolerate spurious returns from raw_wait(). 370 THREAD->_ParkEvent->reset() ; 371 OrderAccess::fence() ; 372 373 // check interrupt event 374 if (interruptible && Thread::is_interrupted(THREAD, true)) { 375 return OM_INTERRUPTED; 376 } 377 378 intptr_t save = _recursions ; 379 _recursions = 0 ; 380 _waiters ++ ; 381 if (THREAD->is_Java_thread()) { 382 guarantee (((JavaThread *) THREAD)->thread_state() == _thread_blocked, "invariant") ; 383 ((JavaThread *)THREAD)->set_suspend_equivalent(); 384 } 385 int rv = SimpleWait (THREAD, millis) ; 386 _recursions = save ; 387 _waiters -- ; 388 389 guarantee (THREAD == _owner, "invariant") ; 390 if (THREAD->is_Java_thread()) { 391 JavaThread * jSelf = (JavaThread *) THREAD ; 392 for (;;) { 393 if (!jSelf->handle_special_suspend_equivalent_condition()) break ; 394 SimpleExit (THREAD) ; 395 jSelf->java_suspend_self(); 396 SimpleEnter (THREAD) ; 397 jSelf->set_suspend_equivalent() ; 398 } 399 } 400 guarantee (THREAD == _owner, "invariant") ; 401 402 if (interruptible && Thread::is_interrupted(THREAD, true)) { 403 return OM_INTERRUPTED; 404 } 405 return OM_OK ; 406 } 407 408 int JvmtiRawMonitor::raw_notify(TRAPS) { 409 TEVENT (raw_notify) ; 410 if (THREAD != _owner) { 411 return OM_ILLEGAL_MONITOR_STATE; 412 } 413 SimpleNotify (THREAD, false) ; 414 return OM_OK; 415 } 416 417 int JvmtiRawMonitor::raw_notifyAll(TRAPS) { 418 TEVENT (raw_notifyAll) ; 419 if (THREAD != _owner) { 420 return OM_ILLEGAL_MONITOR_STATE; 421 } 422 SimpleNotify (THREAD, true) ; 423 return OM_OK; 424 }