mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-29 20:48:29 +00:00
8351046: Rename ObjectMonitor functions
Reviewed-by: stefank, fbredberg
This commit is contained in:
parent
e90b6bdb87
commit
d90b79a2bd
@ -127,7 +127,7 @@ ParkEvent* ObjectMonitor::_vthread_unparker_ParkEvent = nullptr;
|
||||
// its owner_id (return value from owner_id_from()).
|
||||
//
|
||||
// * Invariant: A thread appears on at most one monitor list --
|
||||
// entry_list or WaitSet -- at any one time.
|
||||
// entry_list or wait_set -- at any one time.
|
||||
//
|
||||
// * Contending threads "push" themselves onto the entry_list with CAS
|
||||
// and then spin/park.
|
||||
@ -252,10 +252,10 @@ ParkEvent* ObjectMonitor::_vthread_unparker_ParkEvent = nullptr;
|
||||
// the semantics of park-unpark. Put another way, this monitor implementation
|
||||
// depends only on atomic operations and park-unpark.
|
||||
//
|
||||
// * Waiting threads reside on the WaitSet list -- wait() puts
|
||||
// the caller onto the WaitSet.
|
||||
// * Waiting threads reside on the wait_set list -- wait() puts
|
||||
// the caller onto the wait_set.
|
||||
//
|
||||
// * notify() or notifyAll() simply transfers threads from the WaitSet
|
||||
// * notify() or notifyAll() simply transfers threads from the wait_set
|
||||
// to the entry_list. Subsequent exit() operations will
|
||||
// unpark/re-schedule the notifyee. Unparking/re-scheduling a
|
||||
// notifyee in notify() is inefficient - it's likely the notifyee
|
||||
@ -296,9 +296,9 @@ ObjectMonitor::ObjectMonitor(oop object) :
|
||||
_succ(NO_OWNER),
|
||||
_SpinDuration(ObjectMonitor::Knob_SpinLimit),
|
||||
_contentions(0),
|
||||
_WaitSet(nullptr),
|
||||
_wait_set(nullptr),
|
||||
_waiters(0),
|
||||
_WaitSetLock(0),
|
||||
_wait_set_lock(0),
|
||||
_stack_locker(nullptr)
|
||||
{ }
|
||||
|
||||
@ -357,7 +357,7 @@ bool ObjectMonitor::enter_is_async_deflating() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ObjectMonitor::TryLockWithContentionMark(JavaThread* locking_thread, ObjectMonitorContentionMark& contention_mark) {
|
||||
bool ObjectMonitor::try_lock_with_contention_mark(JavaThread* locking_thread, ObjectMonitorContentionMark& contention_mark) {
|
||||
assert(contention_mark._monitor == this, "must be");
|
||||
assert(!is_being_async_deflated(), "must be");
|
||||
|
||||
@ -404,7 +404,7 @@ void ObjectMonitor::enter_for_with_contention_mark(JavaThread* locking_thread, O
|
||||
// The monitor is private to or already owned by locking_thread which must be suspended.
|
||||
// So this code may only contend with deflation.
|
||||
assert(locking_thread == Thread::current() || locking_thread->is_obj_deopt_suspend(), "must be");
|
||||
bool success = TryLockWithContentionMark(locking_thread, contention_mark);
|
||||
bool success = try_lock_with_contention_mark(locking_thread, contention_mark);
|
||||
|
||||
assert(success, "Failed to enter_for: locking_thread=" INTPTR_FORMAT
|
||||
", this=" INTPTR_FORMAT "{owner=" INT64_FORMAT "}",
|
||||
@ -425,7 +425,7 @@ bool ObjectMonitor::enter_for(JavaThread* locking_thread) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool success = TryLockWithContentionMark(locking_thread, contention_mark);
|
||||
bool success = try_lock_with_contention_mark(locking_thread, contention_mark);
|
||||
|
||||
assert(success, "Failed to enter_for: locking_thread=" INTPTR_FORMAT
|
||||
", this=" INTPTR_FORMAT "{owner=" INT64_FORMAT "}",
|
||||
@ -436,7 +436,7 @@ bool ObjectMonitor::enter_for(JavaThread* locking_thread) {
|
||||
|
||||
bool ObjectMonitor::try_enter(JavaThread* current, bool check_for_recursion) {
|
||||
// TryLock avoids the CAS and handles deflation.
|
||||
TryLockResult r = TryLock(current);
|
||||
TryLockResult r = try_lock(current);
|
||||
if (r == TryLockResult::Success) {
|
||||
assert(_recursions == 0, "invariant");
|
||||
return true;
|
||||
@ -474,7 +474,7 @@ bool ObjectMonitor::spin_enter(JavaThread* current) {
|
||||
// Do one round of spinning.
|
||||
// Note that if we acquire the monitor from an initial spin
|
||||
// we forgo posting JVMTI events and firing DTRACE probes.
|
||||
if (TrySpin(current)) {
|
||||
if (try_spin(current)) {
|
||||
assert(has_owner(current), "must be current: owner=" INT64_FORMAT, owner_raw());
|
||||
assert(_recursions == 0, "must be 0: recursions=%zd", _recursions);
|
||||
assert_mark_word_consistency();
|
||||
@ -551,7 +551,7 @@ void ObjectMonitor::enter_with_contention_mark(JavaThread* current, ObjectMonito
|
||||
notify_contended_enter(current);
|
||||
result = Continuation::try_preempt(current, ce->cont_oop(current));
|
||||
if (result == freeze_ok) {
|
||||
bool acquired = VThreadMonitorEnter(current);
|
||||
bool acquired = vthread_monitor_enter(current);
|
||||
if (acquired) {
|
||||
// We actually acquired the monitor while trying to add the vthread to the
|
||||
// _entry_list so cancel preemption. We will still go through the preempt stub
|
||||
@ -586,7 +586,7 @@ void ObjectMonitor::enter_with_contention_mark(JavaThread* current, ObjectMonito
|
||||
ExitOnSuspend eos(this);
|
||||
{
|
||||
ThreadBlockInVMPreprocess<ExitOnSuspend> tbivs(current, eos, true /* allow_suspend */);
|
||||
EnterI(current);
|
||||
enter_internal(current);
|
||||
current->set_current_pending_monitor(nullptr);
|
||||
// We can go to a safepoint at the end of this block. If we
|
||||
// do a thread dump during that safepoint, then this thread will show
|
||||
@ -652,10 +652,10 @@ void ObjectMonitor::enter_with_contention_mark(JavaThread* current, ObjectMonito
|
||||
OM_PERFDATA_OP(ContendedLockAttempts, inc());
|
||||
}
|
||||
|
||||
// Caveat: TryLock() is not necessarily serializing if it returns failure.
|
||||
// Caveat: try_lock() is not necessarily serializing if it returns failure.
|
||||
// Callers must compensate as needed.
|
||||
|
||||
ObjectMonitor::TryLockResult ObjectMonitor::TryLock(JavaThread* current) {
|
||||
ObjectMonitor::TryLockResult ObjectMonitor::try_lock(JavaThread* current) {
|
||||
int64_t own = owner_raw();
|
||||
int64_t first_own = own;
|
||||
|
||||
@ -669,7 +669,7 @@ ObjectMonitor::TryLockResult ObjectMonitor::TryLock(JavaThread* current) {
|
||||
// Treat deflation as interference.
|
||||
return TryLockResult::Interference;
|
||||
}
|
||||
if (TryLockWithContentionMark(current, contention_mark)) {
|
||||
if (try_lock_with_contention_mark(current, contention_mark)) {
|
||||
assert(_recursions == 0, "invariant");
|
||||
return TryLockResult::Success;
|
||||
} else {
|
||||
@ -726,7 +726,7 @@ bool ObjectMonitor::try_lock_or_add_to_entry_list(JavaThread* current, ObjectWai
|
||||
|
||||
// Interference - the CAS failed because _entry_list changed. Before
|
||||
// retrying the CAS retry taking the lock as it may now be free.
|
||||
if (TryLock(current) == TryLockResult::Success) {
|
||||
if (try_lock(current) == TryLockResult::Success) {
|
||||
assert(!has_successor(current), "invariant");
|
||||
assert(has_owner(current), "invariant");
|
||||
return true;
|
||||
@ -779,7 +779,7 @@ bool ObjectMonitor::deflate_monitor(Thread* current) {
|
||||
// it which makes it busy so no deflation. Restore owner to
|
||||
// null if it is still DEFLATER_MARKER.
|
||||
if (try_set_owner_from_raw(DEFLATER_MARKER, NO_OWNER) != DEFLATER_MARKER) {
|
||||
// Deferred decrement for the JT EnterI() that cancelled the async deflation.
|
||||
// Deferred decrement for the JT enter_internal() that cancelled the async deflation.
|
||||
add_to_contentions(-1);
|
||||
}
|
||||
return false;
|
||||
@ -792,7 +792,7 @@ bool ObjectMonitor::deflate_monitor(Thread* current) {
|
||||
// ObjectMonitor is now busy. Restore owner to null if it is
|
||||
// still DEFLATER_MARKER:
|
||||
if (try_set_owner_from_raw(DEFLATER_MARKER, NO_OWNER) != DEFLATER_MARKER) {
|
||||
// Deferred decrement for the JT EnterI() that cancelled the async deflation.
|
||||
// Deferred decrement for the JT enter_internal() that cancelled the async deflation.
|
||||
add_to_contentions(-1);
|
||||
}
|
||||
return false;
|
||||
@ -904,11 +904,11 @@ const char* ObjectMonitor::is_busy_to_string(stringStream* ss) {
|
||||
return ss->base();
|
||||
}
|
||||
|
||||
void ObjectMonitor::EnterI(JavaThread* current) {
|
||||
void ObjectMonitor::enter_internal(JavaThread* current) {
|
||||
assert(current->thread_state() == _thread_blocked, "invariant");
|
||||
|
||||
// Try the lock - TATAS
|
||||
if (TryLock(current) == TryLockResult::Success) {
|
||||
if (try_lock(current) == TryLockResult::Success) {
|
||||
assert(!has_successor(current), "invariant");
|
||||
assert(has_owner(current), "invariant");
|
||||
return;
|
||||
@ -923,7 +923,7 @@ void ObjectMonitor::EnterI(JavaThread* current) {
|
||||
// to the owner. This has subtle but beneficial affinity
|
||||
// effects.
|
||||
|
||||
if (TrySpin(current)) {
|
||||
if (try_spin(current)) {
|
||||
assert(has_owner(current), "invariant");
|
||||
assert(!has_successor(current), "invariant");
|
||||
return;
|
||||
@ -977,7 +977,7 @@ void ObjectMonitor::EnterI(JavaThread* current) {
|
||||
|
||||
for (;;) {
|
||||
|
||||
if (TryLock(current) == TryLockResult::Success) {
|
||||
if (try_lock(current) == TryLockResult::Success) {
|
||||
break;
|
||||
}
|
||||
assert(!has_owner(current), "invariant");
|
||||
@ -994,7 +994,7 @@ void ObjectMonitor::EnterI(JavaThread* current) {
|
||||
current->_ParkEvent->park();
|
||||
}
|
||||
|
||||
if (TryLock(current) == TryLockResult::Success) {
|
||||
if (try_lock(current) == TryLockResult::Success) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1010,9 +1010,9 @@ void ObjectMonitor::EnterI(JavaThread* current) {
|
||||
|
||||
// Assuming this is not a spurious wakeup we'll normally find _succ == current.
|
||||
// We can defer clearing _succ until after the spin completes
|
||||
// TrySpin() must tolerate being called with _succ == current.
|
||||
// try_spin() must tolerate being called with _succ == current.
|
||||
// Try yet another round of adaptive spinning.
|
||||
if (TrySpin(current)) {
|
||||
if (try_spin(current)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1030,7 +1030,7 @@ void ObjectMonitor::EnterI(JavaThread* current) {
|
||||
|
||||
// Egress :
|
||||
// Current has acquired the lock -- Unlink current from the _entry_list.
|
||||
UnlinkAfterAcquire(current, &node);
|
||||
unlink_after_acquire(current, &node);
|
||||
if (has_successor(current)) {
|
||||
clear_successor();
|
||||
// Note that we don't need to do OrderAccess::fence() after clearing
|
||||
@ -1062,13 +1062,13 @@ void ObjectMonitor::EnterI(JavaThread* current) {
|
||||
return;
|
||||
}
|
||||
|
||||
// ReenterI() is a specialized inline form of the latter half of the
|
||||
// contended slow-path from EnterI(). We use ReenterI() only for
|
||||
// reenter_internal() is a specialized inline form of the latter half of the
|
||||
// contended slow-path from enter_internal(). We use reenter_internal() only for
|
||||
// monitor reentry in wait().
|
||||
//
|
||||
// In the future we should reconcile EnterI() and ReenterI().
|
||||
// In the future we should reconcile enter_internal() and reenter_internal().
|
||||
|
||||
void ObjectMonitor::ReenterI(JavaThread* current, ObjectWaiter* currentNode) {
|
||||
void ObjectMonitor::reenter_internal(JavaThread* current, ObjectWaiter* currentNode) {
|
||||
assert(current != nullptr, "invariant");
|
||||
assert(current->thread_state() != _thread_blocked, "invariant");
|
||||
assert(currentNode != nullptr, "invariant");
|
||||
@ -1082,13 +1082,13 @@ void ObjectMonitor::ReenterI(JavaThread* current, ObjectWaiter* currentNode) {
|
||||
assert(!has_owner(current), "invariant");
|
||||
|
||||
// This thread has been notified so try to reacquire the lock.
|
||||
if (TryLock(current) == TryLockResult::Success) {
|
||||
if (try_lock(current) == TryLockResult::Success) {
|
||||
break;
|
||||
}
|
||||
|
||||
// If that fails, spin again. Note that spin count may be zero so the above TryLock
|
||||
// is necessary.
|
||||
if (TrySpin(current)) {
|
||||
if (try_spin(current)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1107,7 +1107,7 @@ void ObjectMonitor::ReenterI(JavaThread* current, ObjectWaiter* currentNode) {
|
||||
// Try again, but just so we distinguish between futile wakeups and
|
||||
// successful wakeups. The following test isn't algorithmically
|
||||
// necessary, but it helps us maintain sensible statistics.
|
||||
if (TryLock(current) == TryLockResult::Success) {
|
||||
if (try_lock(current) == TryLockResult::Success) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1131,11 +1131,11 @@ void ObjectMonitor::ReenterI(JavaThread* current, ObjectWaiter* currentNode) {
|
||||
// Current has acquired the lock -- Unlink current from the _entry_list.
|
||||
assert(has_owner(current), "invariant");
|
||||
assert_mark_word_consistency();
|
||||
UnlinkAfterAcquire(current, currentNode);
|
||||
unlink_after_acquire(current, currentNode);
|
||||
if (has_successor(current)) clear_successor();
|
||||
assert(!has_successor(current), "invariant");
|
||||
currentNode->TState = ObjectWaiter::TS_RUN;
|
||||
OrderAccess::fence(); // see comments at the end of EnterI()
|
||||
OrderAccess::fence(); // see comments at the end of enter_internal()
|
||||
}
|
||||
|
||||
// This method is called from two places:
|
||||
@ -1144,8 +1144,8 @@ void ObjectMonitor::ReenterI(JavaThread* current, ObjectWaiter* currentNode) {
|
||||
// monitor, with the existing waiter.
|
||||
// For the Object.wait() case we do not delete the ObjectWaiter in case we
|
||||
// succesfully acquire the monitor since we are going to need it on return.
|
||||
bool ObjectMonitor::VThreadMonitorEnter(JavaThread* current, ObjectWaiter* waiter) {
|
||||
if (TryLock(current) == TryLockResult::Success) {
|
||||
bool ObjectMonitor::vthread_monitor_enter(JavaThread* current, ObjectWaiter* waiter) {
|
||||
if (try_lock(current) == TryLockResult::Success) {
|
||||
assert(has_owner(current), "invariant");
|
||||
assert(!has_successor(current), "invariant");
|
||||
return true;
|
||||
@ -1162,9 +1162,9 @@ bool ObjectMonitor::VThreadMonitorEnter(JavaThread* current, ObjectWaiter* waite
|
||||
|
||||
// We have to try once more since owner could have exited monitor and checked
|
||||
// _entry_list before we added the node to the queue.
|
||||
if (TryLock(current) == TryLockResult::Success) {
|
||||
if (try_lock(current) == TryLockResult::Success) {
|
||||
assert(has_owner(current), "invariant");
|
||||
UnlinkAfterAcquire(current, node);
|
||||
unlink_after_acquire(current, node);
|
||||
if (has_successor(current)) clear_successor();
|
||||
if (waiter == nullptr) delete node; // for Object.wait() don't delete yet
|
||||
return true;
|
||||
@ -1188,7 +1188,7 @@ bool ObjectMonitor::resume_operation(JavaThread* current, ObjectWaiter* node, Co
|
||||
assert(!has_owner(current), "");
|
||||
|
||||
if (node->is_wait() && !node->at_reenter()) {
|
||||
bool acquired_monitor = VThreadWaitReenter(current, node, cont);
|
||||
bool acquired_monitor = vthread_wait_reenter(current, node, cont);
|
||||
if (acquired_monitor) return true;
|
||||
}
|
||||
|
||||
@ -1197,8 +1197,8 @@ bool ObjectMonitor::resume_operation(JavaThread* current, ObjectWaiter* node, Co
|
||||
int state = node->TState;
|
||||
guarantee(state == ObjectWaiter::TS_ENTER, "invariant");
|
||||
|
||||
if (TryLock(current) == TryLockResult::Success) {
|
||||
VThreadEpilog(current, node);
|
||||
if (try_lock(current) == TryLockResult::Success) {
|
||||
vthread_epilog(current, node);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1208,8 +1208,8 @@ bool ObjectMonitor::resume_operation(JavaThread* current, ObjectWaiter* node, Co
|
||||
// Invariant: after clearing _succ a thread *must* retry acquiring the monitor.
|
||||
OrderAccess::fence();
|
||||
|
||||
if (TryLock(current) == TryLockResult::Success) {
|
||||
VThreadEpilog(current, node);
|
||||
if (try_lock(current) == TryLockResult::Success) {
|
||||
vthread_epilog(current, node);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1219,7 +1219,7 @@ bool ObjectMonitor::resume_operation(JavaThread* current, ObjectWaiter* node, Co
|
||||
return false;
|
||||
}
|
||||
|
||||
void ObjectMonitor::VThreadEpilog(JavaThread* current, ObjectWaiter* node) {
|
||||
void ObjectMonitor::vthread_epilog(JavaThread* current, ObjectWaiter* node) {
|
||||
assert(has_owner(current), "invariant");
|
||||
add_to_contentions(-1);
|
||||
|
||||
@ -1237,7 +1237,7 @@ void ObjectMonitor::VThreadEpilog(JavaThread* current, ObjectWaiter* node) {
|
||||
}
|
||||
}
|
||||
|
||||
UnlinkAfterAcquire(current, node);
|
||||
unlink_after_acquire(current, node);
|
||||
delete node;
|
||||
|
||||
// Clear the ObjectWaiter* from the vthread.
|
||||
@ -1283,7 +1283,7 @@ ObjectWaiter* ObjectMonitor::entry_list_tail(JavaThread* current) {
|
||||
// The head of _entry_list is volatile but the interior is stable.
|
||||
// In addition, current.TState is stable.
|
||||
|
||||
void ObjectMonitor::UnlinkAfterAcquire(JavaThread* current, ObjectWaiter* currentNode) {
|
||||
void ObjectMonitor::unlink_after_acquire(JavaThread* current, ObjectWaiter* currentNode) {
|
||||
assert(has_owner(current), "invariant");
|
||||
assert((!currentNode->is_vthread() && currentNode->thread() == current) ||
|
||||
(currentNode->is_vthread() && currentNode->vthread() == current->vthread()), "invariant");
|
||||
@ -1389,7 +1389,7 @@ void ObjectMonitor::UnlinkAfterAcquire(JavaThread* current, ObjectWaiter* curren
|
||||
// inopportune) reclamation of "this".
|
||||
//
|
||||
// We'd like to assert that: (THREAD->thread_state() != _thread_blocked) ;
|
||||
// There's one exception to the claim above, however. EnterI() can call
|
||||
// There's one exception to the claim above, however. enter_internal() can call
|
||||
// exit() to drop a lock if the acquirer has been externally suspended.
|
||||
// In that case exit() is called with _thread_state == _thread_blocked,
|
||||
// but the monitor's _contentions field is > 0, which inhibits reclamation.
|
||||
@ -1510,7 +1510,7 @@ void ObjectMonitor::exit(JavaThread* current, bool not_suspended) {
|
||||
// reacquire the lock. If we fail to reacquire the lock the
|
||||
// responsibility for ensuring succession falls to the new owner.
|
||||
|
||||
if (TryLock(current) != TryLockResult::Success) {
|
||||
if (try_lock(current) != TryLockResult::Success) {
|
||||
// Some other thread acquired the lock (or the monitor was
|
||||
// deflated). Either way we are done.
|
||||
return;
|
||||
@ -1535,13 +1535,13 @@ void ObjectMonitor::exit(JavaThread* current, bool not_suspended) {
|
||||
// Given all that, we have to tolerate the circumstance where "w" is
|
||||
// associated with current.
|
||||
assert(w->TState == ObjectWaiter::TS_ENTER, "invariant");
|
||||
ExitEpilog(current, w);
|
||||
exit_epilog(current, w);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectMonitor::ExitEpilog(JavaThread* current, ObjectWaiter* Wakee) {
|
||||
void ObjectMonitor::exit_epilog(JavaThread* current, ObjectWaiter* Wakee) {
|
||||
assert(has_owner(current), "invariant");
|
||||
|
||||
// Exit protocol:
|
||||
@ -1735,7 +1735,7 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
|
||||
current->set_current_waiting_monitor(this);
|
||||
result = Continuation::try_preempt(current, ce->cont_oop(current));
|
||||
if (result == freeze_ok) {
|
||||
VThreadWait(current, millis);
|
||||
vthread_wait(current, millis);
|
||||
current->set_current_waiting_monitor(nullptr);
|
||||
return;
|
||||
}
|
||||
@ -1765,14 +1765,14 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
|
||||
|
||||
// Enter the waiting queue, which is a circular doubly linked list in this case
|
||||
// but it could be a priority queue or any data structure.
|
||||
// _WaitSetLock protects the wait queue. Normally the wait queue is accessed only
|
||||
// _wait_set_lock protects the wait queue. Normally the wait queue is accessed only
|
||||
// by the owner of the monitor *except* in the case where park()
|
||||
// returns because of a timeout of interrupt. Contention is exceptionally rare
|
||||
// so we use a simple spin-lock instead of a heavier-weight blocking lock.
|
||||
|
||||
Thread::SpinAcquire(&_WaitSetLock, "WaitSet - add");
|
||||
AddWaiter(&node);
|
||||
Thread::SpinRelease(&_WaitSetLock);
|
||||
Thread::SpinAcquire(&_wait_set_lock, "wait_set - add");
|
||||
add_waiter(&node);
|
||||
Thread::SpinRelease(&_wait_set_lock);
|
||||
|
||||
intx save = _recursions; // record the old recursion count
|
||||
_waiters++; // increment the number of waiters
|
||||
@ -1780,7 +1780,7 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
|
||||
exit(current); // exit the monitor
|
||||
guarantee(!has_owner(current), "invariant");
|
||||
|
||||
// The thread is on the WaitSet list - now park() it.
|
||||
// The thread is on the wait_set list - now park() it.
|
||||
// On MP systems it's conceivable that a brief spin before we park
|
||||
// could be profitable.
|
||||
//
|
||||
@ -1813,10 +1813,10 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
|
||||
}
|
||||
}
|
||||
|
||||
// Node may be on the WaitSet, or on the entry_list, or in transition
|
||||
// from the WaitSet to the entry_list.
|
||||
// See if we need to remove Node from the WaitSet.
|
||||
// We use double-checked locking to avoid grabbing _WaitSetLock
|
||||
// Node may be on the wait_set, or on the entry_list, or in transition
|
||||
// from the wait_set to the entry_list.
|
||||
// See if we need to remove Node from the wait_set.
|
||||
// We use double-checked locking to avoid grabbing _wait_set_lock
|
||||
// if the thread is not on the wait queue.
|
||||
//
|
||||
// Note that we don't need a fence before the fetch of TState.
|
||||
@ -1829,13 +1829,13 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
|
||||
// That is, we fail toward safety.
|
||||
|
||||
if (node.TState == ObjectWaiter::TS_WAIT) {
|
||||
Thread::SpinAcquire(&_WaitSetLock, "WaitSet - unlink");
|
||||
Thread::SpinAcquire(&_wait_set_lock, "wait_set - unlink");
|
||||
if (node.TState == ObjectWaiter::TS_WAIT) {
|
||||
DequeueSpecificWaiter(&node); // unlink from WaitSet
|
||||
dequeue_specific_waiter(&node); // unlink from wait_set
|
||||
assert(!node._notified, "invariant");
|
||||
node.TState = ObjectWaiter::TS_RUN;
|
||||
}
|
||||
Thread::SpinRelease(&_WaitSetLock);
|
||||
Thread::SpinRelease(&_wait_set_lock);
|
||||
}
|
||||
|
||||
// The thread is now either on off-list (TS_RUN),
|
||||
@ -1894,7 +1894,7 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
|
||||
enter(current);
|
||||
} else {
|
||||
guarantee(v == ObjectWaiter::TS_ENTER, "invariant");
|
||||
ReenterI(current, &node);
|
||||
reenter_internal(current, &node);
|
||||
node.wait_reenter_end(this);
|
||||
}
|
||||
|
||||
@ -1940,12 +1940,12 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
|
||||
|
||||
// Consider:
|
||||
// If the lock is cool (entry_list == null && succ == null) and we're on an MP system
|
||||
// then instead of transferring a thread from the WaitSet to the entry_list
|
||||
// we might just dequeue a thread from the WaitSet and directly unpark() it.
|
||||
// then instead of transferring a thread from the wait_set to the entry_list
|
||||
// we might just dequeue a thread from the wait_set and directly unpark() it.
|
||||
|
||||
void ObjectMonitor::INotify(JavaThread* current) {
|
||||
Thread::SpinAcquire(&_WaitSetLock, "WaitSet - notify");
|
||||
ObjectWaiter* iterator = DequeueWaiter();
|
||||
void ObjectMonitor::notify_internal(JavaThread* current) {
|
||||
Thread::SpinAcquire(&_wait_set_lock, "wait_set - notify");
|
||||
ObjectWaiter* iterator = dequeue_waiter();
|
||||
if (iterator != nullptr) {
|
||||
guarantee(iterator->TState == ObjectWaiter::TS_WAIT, "invariant");
|
||||
guarantee(!iterator->_notified, "invariant");
|
||||
@ -1970,19 +1970,19 @@ void ObjectMonitor::INotify(JavaThread* current) {
|
||||
iterator->_notifier_tid = JFR_THREAD_ID(current);
|
||||
add_to_entry_list(current, iterator);
|
||||
|
||||
// _WaitSetLock protects the wait queue, not the entry_list. We could
|
||||
// _wait_set_lock protects the wait queue, not the entry_list. We could
|
||||
// move the add-to-entry_list operation, above, outside the critical section
|
||||
// protected by _WaitSetLock. In practice that's not useful. With the
|
||||
// protected by _wait_set_lock. In practice that's not useful. With the
|
||||
// exception of wait() timeouts and interrupts the monitor owner
|
||||
// is the only thread that grabs _WaitSetLock. There's almost no contention
|
||||
// on _WaitSetLock so it's not profitable to reduce the length of the
|
||||
// is the only thread that grabs _wait_set_lock. There's almost no contention
|
||||
// on _wait_set_lock so it's not profitable to reduce the length of the
|
||||
// critical section.
|
||||
|
||||
if (!iterator->is_vthread()) {
|
||||
iterator->wait_reenter_begin(this);
|
||||
}
|
||||
}
|
||||
Thread::SpinRelease(&_WaitSetLock);
|
||||
Thread::SpinRelease(&_wait_set_lock);
|
||||
}
|
||||
|
||||
// Consider: a not-uncommon synchronization bug is to use notify() when
|
||||
@ -1998,11 +1998,11 @@ void ObjectMonitor::INotify(JavaThread* current) {
|
||||
void ObjectMonitor::notify(TRAPS) {
|
||||
JavaThread* current = THREAD;
|
||||
CHECK_OWNER(); // Throws IMSE if not owner.
|
||||
if (_WaitSet == nullptr) {
|
||||
if (_wait_set == nullptr) {
|
||||
return;
|
||||
}
|
||||
DTRACE_MONITOR_PROBE(notify, this, object(), current);
|
||||
INotify(current);
|
||||
notify_internal(current);
|
||||
OM_PERFDATA_OP(Notifications, inc(1));
|
||||
}
|
||||
|
||||
@ -2015,21 +2015,21 @@ void ObjectMonitor::notify(TRAPS) {
|
||||
void ObjectMonitor::notifyAll(TRAPS) {
|
||||
JavaThread* current = THREAD;
|
||||
CHECK_OWNER(); // Throws IMSE if not owner.
|
||||
if (_WaitSet == nullptr) {
|
||||
if (_wait_set == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
DTRACE_MONITOR_PROBE(notifyAll, this, object(), current);
|
||||
int tally = 0;
|
||||
while (_WaitSet != nullptr) {
|
||||
while (_wait_set != nullptr) {
|
||||
tally++;
|
||||
INotify(current);
|
||||
notify_internal(current);
|
||||
}
|
||||
|
||||
OM_PERFDATA_OP(Notifications, inc(tally));
|
||||
}
|
||||
|
||||
void ObjectMonitor::VThreadWait(JavaThread* current, jlong millis) {
|
||||
void ObjectMonitor::vthread_wait(JavaThread* current, jlong millis) {
|
||||
oop vthread = current->vthread();
|
||||
ObjectWaiter* node = new ObjectWaiter(vthread, this);
|
||||
node->_is_wait = true;
|
||||
@ -2038,14 +2038,14 @@ void ObjectMonitor::VThreadWait(JavaThread* current, jlong millis) {
|
||||
|
||||
// Enter the waiting queue, which is a circular doubly linked list in this case
|
||||
// but it could be a priority queue or any data structure.
|
||||
// _WaitSetLock protects the wait queue. Normally the wait queue is accessed only
|
||||
// _wait_set_lock protects the wait queue. Normally the wait queue is accessed only
|
||||
// by the owner of the monitor *except* in the case where park()
|
||||
// returns because of a timeout or interrupt. Contention is exceptionally rare
|
||||
// so we use a simple spin-lock instead of a heavier-weight blocking lock.
|
||||
|
||||
Thread::SpinAcquire(&_WaitSetLock, "WaitSet - add");
|
||||
AddWaiter(node);
|
||||
Thread::SpinRelease(&_WaitSetLock);
|
||||
Thread::SpinAcquire(&_wait_set_lock, "wait_set - add");
|
||||
add_waiter(node);
|
||||
Thread::SpinRelease(&_wait_set_lock);
|
||||
|
||||
node->_recursions = _recursions; // record the old recursion count
|
||||
_recursions = 0; // set the recursion level to be 0
|
||||
@ -2061,18 +2061,18 @@ void ObjectMonitor::VThreadWait(JavaThread* current, jlong millis) {
|
||||
java_lang_VirtualThread::set_objectWaiter(vthread, node);
|
||||
}
|
||||
|
||||
bool ObjectMonitor::VThreadWaitReenter(JavaThread* current, ObjectWaiter* node, ContinuationWrapper& cont) {
|
||||
bool ObjectMonitor::vthread_wait_reenter(JavaThread* current, ObjectWaiter* node, ContinuationWrapper& cont) {
|
||||
// The first time we run after being preempted on Object.wait() we
|
||||
// need to check if we were interrupted or the wait timed-out, and
|
||||
// in that case remove ourselves from the _WaitSet queue.
|
||||
// in that case remove ourselves from the _wait_set queue.
|
||||
if (node->TState == ObjectWaiter::TS_WAIT) {
|
||||
Thread::SpinAcquire(&_WaitSetLock, "WaitSet - unlink");
|
||||
Thread::SpinAcquire(&_wait_set_lock, "wait_set - unlink");
|
||||
if (node->TState == ObjectWaiter::TS_WAIT) {
|
||||
DequeueSpecificWaiter(node); // unlink from WaitSet
|
||||
dequeue_specific_waiter(node); // unlink from wait_set
|
||||
assert(!node->_notified, "invariant");
|
||||
node->TState = ObjectWaiter::TS_RUN;
|
||||
}
|
||||
Thread::SpinRelease(&_WaitSetLock);
|
||||
Thread::SpinRelease(&_wait_set_lock);
|
||||
}
|
||||
|
||||
// If this was an interrupted case, set the _interrupted boolean so that
|
||||
@ -2092,7 +2092,7 @@ bool ObjectMonitor::VThreadWaitReenter(JavaThread* current, ObjectWaiter* node,
|
||||
node->_at_reenter = true;
|
||||
|
||||
if (!was_notified) {
|
||||
bool acquired = VThreadMonitorEnter(current, node);
|
||||
bool acquired = vthread_monitor_enter(current, node);
|
||||
if (acquired) {
|
||||
guarantee(_recursions == 0, "invariant");
|
||||
_recursions = node->_recursions; // restore the old recursion count
|
||||
@ -2212,7 +2212,7 @@ inline static int adjust_down(int spin_duration) {
|
||||
|
||||
bool ObjectMonitor::short_fixed_spin(JavaThread* current, int spin_count, bool adapt) {
|
||||
for (int ctr = 0; ctr < spin_count; ctr++) {
|
||||
TryLockResult status = TryLock(current);
|
||||
TryLockResult status = try_lock(current);
|
||||
if (status == TryLockResult::Success) {
|
||||
if (adapt) {
|
||||
_SpinDuration = adjust_up(_SpinDuration);
|
||||
@ -2227,7 +2227,7 @@ bool ObjectMonitor::short_fixed_spin(JavaThread* current, int spin_count, bool a
|
||||
}
|
||||
|
||||
// Spinning: Fixed frequency (100%), vary duration
|
||||
bool ObjectMonitor::TrySpin(JavaThread* current) {
|
||||
bool ObjectMonitor::try_spin(JavaThread* current) {
|
||||
|
||||
// Dumb, brutal spin. Good for comparative measurements against adaptive spinning.
|
||||
int knob_fixed_spin = Knob_FixedSpin; // 0 (don't spin: default), 2000 good test
|
||||
@ -2352,10 +2352,10 @@ bool ObjectMonitor::TrySpin(JavaThread* current) {
|
||||
clear_successor();
|
||||
// Invariant: after setting succ=null a contending thread
|
||||
// must recheck-retry _owner before parking. This usually happens
|
||||
// in the normal usage of TrySpin(), but it's safest
|
||||
// to make TrySpin() as foolproof as possible.
|
||||
// in the normal usage of try_spin(), but it's safest
|
||||
// to make try_spin() as foolproof as possible.
|
||||
OrderAccess::fence();
|
||||
if (TryLock(current) == TryLockResult::Success) {
|
||||
if (try_lock(current) == TryLockResult::Success) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -2365,7 +2365,7 @@ bool ObjectMonitor::TrySpin(JavaThread* current) {
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// WaitSet management ...
|
||||
// wait_set management ...
|
||||
|
||||
ObjectWaiter::ObjectWaiter(JavaThread* current) {
|
||||
_next = nullptr;
|
||||
@ -2407,17 +2407,17 @@ void ObjectWaiter::wait_reenter_end(ObjectMonitor * const mon) {
|
||||
JavaThreadBlockedOnMonitorEnterState::wait_reenter_end(_thread, _active);
|
||||
}
|
||||
|
||||
inline void ObjectMonitor::AddWaiter(ObjectWaiter* node) {
|
||||
inline void ObjectMonitor::add_waiter(ObjectWaiter* node) {
|
||||
assert(node != nullptr, "should not add null node");
|
||||
assert(node->_prev == nullptr, "node already in list");
|
||||
assert(node->_next == nullptr, "node already in list");
|
||||
// put node at end of queue (circular doubly linked list)
|
||||
if (_WaitSet == nullptr) {
|
||||
_WaitSet = node;
|
||||
if (_wait_set == nullptr) {
|
||||
_wait_set = node;
|
||||
node->_prev = node;
|
||||
node->_next = node;
|
||||
} else {
|
||||
ObjectWaiter* head = _WaitSet;
|
||||
ObjectWaiter* head = _wait_set;
|
||||
ObjectWaiter* tail = head->_prev;
|
||||
assert(tail->_next == head, "invariant check");
|
||||
tail->_next = node;
|
||||
@ -2427,16 +2427,16 @@ inline void ObjectMonitor::AddWaiter(ObjectWaiter* node) {
|
||||
}
|
||||
}
|
||||
|
||||
inline ObjectWaiter* ObjectMonitor::DequeueWaiter() {
|
||||
inline ObjectWaiter* ObjectMonitor::dequeue_waiter() {
|
||||
// dequeue the very first waiter
|
||||
ObjectWaiter* waiter = _WaitSet;
|
||||
ObjectWaiter* waiter = _wait_set;
|
||||
if (waiter) {
|
||||
DequeueSpecificWaiter(waiter);
|
||||
dequeue_specific_waiter(waiter);
|
||||
}
|
||||
return waiter;
|
||||
}
|
||||
|
||||
inline void ObjectMonitor::DequeueSpecificWaiter(ObjectWaiter* node) {
|
||||
inline void ObjectMonitor::dequeue_specific_waiter(ObjectWaiter* node) {
|
||||
assert(node != nullptr, "should not dequeue nullptr node");
|
||||
assert(node->_prev != nullptr, "node already removed from list");
|
||||
assert(node->_next != nullptr, "node already removed from list");
|
||||
@ -2446,15 +2446,15 @@ inline void ObjectMonitor::DequeueSpecificWaiter(ObjectWaiter* node) {
|
||||
ObjectWaiter* next = node->_next;
|
||||
if (next == node) {
|
||||
assert(node->_prev == node, "invariant check");
|
||||
_WaitSet = nullptr;
|
||||
_wait_set = nullptr;
|
||||
} else {
|
||||
ObjectWaiter* prev = node->_prev;
|
||||
assert(prev->_next == node, "invariant check");
|
||||
assert(next->_prev == node, "invariant check");
|
||||
next->_prev = prev;
|
||||
prev->_next = next;
|
||||
if (_WaitSet == node) {
|
||||
_WaitSet = next;
|
||||
if (_wait_set == node) {
|
||||
_wait_set = next;
|
||||
}
|
||||
}
|
||||
node->_next = nullptr;
|
||||
@ -2554,9 +2554,9 @@ void ObjectMonitor::print() const { print_on(tty); }
|
||||
// _succ = 0x0000000000000000
|
||||
// _SpinDuration = 5000
|
||||
// _contentions = 0
|
||||
// _WaitSet = 0x0000700009756248
|
||||
// _wait_set = 0x0000700009756248
|
||||
// _waiters = 1
|
||||
// _WaitSetLock = 0
|
||||
// _wait_set_lock = 0
|
||||
// }
|
||||
//
|
||||
void ObjectMonitor::print_debug_style_on(outputStream* st) const {
|
||||
@ -2582,9 +2582,9 @@ void ObjectMonitor::print_debug_style_on(outputStream* st) const {
|
||||
st->print_cr(" _succ = " INT64_FORMAT, successor());
|
||||
st->print_cr(" _SpinDuration = %d", _SpinDuration);
|
||||
st->print_cr(" _contentions = %d", contentions());
|
||||
st->print_cr(" _WaitSet = " INTPTR_FORMAT, p2i(_WaitSet));
|
||||
st->print_cr(" _wait_set = " INTPTR_FORMAT, p2i(_wait_set));
|
||||
st->print_cr(" _waiters = %d", _waiters);
|
||||
st->print_cr(" _WaitSetLock = %d", _WaitSetLock);
|
||||
st->print_cr(" _wait_set_lock = %d", _wait_set_lock);
|
||||
st->print_cr("}");
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -203,9 +203,9 @@ class ObjectMonitor : public CHeapObj<mtObjectMonitor> {
|
||||
// deflated. It is also used by the async deflation protocol. See
|
||||
// ObjectMonitor::deflate_monitor().
|
||||
|
||||
ObjectWaiter* volatile _WaitSet; // LL of threads wait()ing on the monitor
|
||||
ObjectWaiter* volatile _wait_set; // LL of threads waiting on the monitor - wait()
|
||||
volatile int _waiters; // number of waiting threads
|
||||
volatile int _WaitSetLock; // protects Wait Queue - simple spinlock
|
||||
volatile int _wait_set_lock; // protects wait set queue - simple spinlock
|
||||
|
||||
// Used in LM_LEGACY mode to store BasicLock* in case of inflation by contending thread.
|
||||
BasicLock* volatile _stack_locker;
|
||||
@ -375,7 +375,7 @@ class ObjectMonitor : public CHeapObj<mtObjectMonitor> {
|
||||
|
||||
// JVM/TI GetObjectMonitorUsage() needs this:
|
||||
int waiters() const;
|
||||
ObjectWaiter* first_waiter() { return _WaitSet; }
|
||||
ObjectWaiter* first_waiter() { return _wait_set; }
|
||||
ObjectWaiter* next_waiter(ObjectWaiter* o) { return o->_next; }
|
||||
JavaThread* thread_of_waiter(ObjectWaiter* o) { return o->_thread; }
|
||||
|
||||
@ -435,29 +435,29 @@ class ObjectMonitor : public CHeapObj<mtObjectMonitor> {
|
||||
|
||||
private:
|
||||
void add_to_entry_list(JavaThread* current, ObjectWaiter* node);
|
||||
void AddWaiter(ObjectWaiter* waiter);
|
||||
void INotify(JavaThread* current);
|
||||
ObjectWaiter* DequeueWaiter();
|
||||
void DequeueSpecificWaiter(ObjectWaiter* waiter);
|
||||
void EnterI(JavaThread* current);
|
||||
void ReenterI(JavaThread* current, ObjectWaiter* current_node);
|
||||
void UnlinkAfterAcquire(JavaThread* current, ObjectWaiter* current_node);
|
||||
void add_waiter(ObjectWaiter* waiter);
|
||||
void notify_internal(JavaThread* current);
|
||||
ObjectWaiter* dequeue_waiter();
|
||||
void dequeue_specific_waiter(ObjectWaiter* waiter);
|
||||
void enter_internal(JavaThread* current);
|
||||
void reenter_internal(JavaThread* current, ObjectWaiter* current_node);
|
||||
void unlink_after_acquire(JavaThread* current, ObjectWaiter* current_node);
|
||||
ObjectWaiter* entry_list_tail(JavaThread* current);
|
||||
|
||||
bool VThreadMonitorEnter(JavaThread* current, ObjectWaiter* node = nullptr);
|
||||
void VThreadWait(JavaThread* current, jlong millis);
|
||||
bool VThreadWaitReenter(JavaThread* current, ObjectWaiter* node, ContinuationWrapper& cont);
|
||||
void VThreadEpilog(JavaThread* current, ObjectWaiter* node);
|
||||
bool vthread_monitor_enter(JavaThread* current, ObjectWaiter* node = nullptr);
|
||||
void vthread_wait(JavaThread* current, jlong millis);
|
||||
bool vthread_wait_reenter(JavaThread* current, ObjectWaiter* node, ContinuationWrapper& cont);
|
||||
void vthread_epilog(JavaThread* current, ObjectWaiter* node);
|
||||
|
||||
enum class TryLockResult { Interference = -1, HasOwner = 0, Success = 1 };
|
||||
|
||||
bool TryLockWithContentionMark(JavaThread* locking_thread, ObjectMonitorContentionMark& contention_mark);
|
||||
bool try_lock_with_contention_mark(JavaThread* locking_thread, ObjectMonitorContentionMark& contention_mark);
|
||||
bool try_lock_or_add_to_entry_list(JavaThread* current, ObjectWaiter* node);
|
||||
TryLockResult TryLock(JavaThread* current);
|
||||
TryLockResult try_lock(JavaThread* current);
|
||||
|
||||
bool TrySpin(JavaThread* current);
|
||||
bool try_spin(JavaThread* current);
|
||||
bool short_fixed_spin(JavaThread* current, int spin_count, bool adapt);
|
||||
void ExitEpilog(JavaThread* current, ObjectWaiter* Wakee);
|
||||
void exit_epilog(JavaThread* current, ObjectWaiter* Wakee);
|
||||
|
||||
// Deflation support
|
||||
bool deflate_monitor(Thread* current);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -249,7 +249,7 @@ inline ObjectMonitorContentionMark::ObjectMonitorContentionMark(ObjectMonitor* m
|
||||
// contended enter protocol, which prevents the deflater thread from
|
||||
// winning the last part of the 2-part async deflation
|
||||
// protocol. See: ObjectMonitor::deflate_monitor() and
|
||||
// ObjectMonitor::TryLockWithContentionMark().
|
||||
// ObjectMonitor::try_lock_with_contention_mark().
|
||||
_monitor->add_to_contentions(1);
|
||||
}
|
||||
|
||||
@ -261,7 +261,7 @@ inline ObjectMonitorContentionMark::~ObjectMonitorContentionMark() {
|
||||
}
|
||||
|
||||
inline void ObjectMonitorContentionMark::extend() {
|
||||
// Used by ObjectMonitor::TryLockWithContentionMark() to "extend the
|
||||
// Used by ObjectMonitor::try_lock_with_contention_mark() to "extend the
|
||||
// lifetime" of the contention mark.
|
||||
assert(!_extended, "extending twice is probably a bad design");
|
||||
_monitor->add_to_contentions(1);
|
||||
|
||||
@ -374,7 +374,7 @@ bool ObjectSynchronizer::quick_notify(oopDesc* obj, JavaThread* current, bool al
|
||||
}
|
||||
int free_count = 0;
|
||||
do {
|
||||
mon->INotify(current);
|
||||
mon->notify_internal(current);
|
||||
++free_count;
|
||||
} while (mon->first_waiter() != nullptr && all);
|
||||
OM_PERFDATA_OP(Notifications, inc(free_count));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user