8355646: Optimize ObjectMonitor::exit
Reviewed-by: pchilanomate, coleenp
This commit is contained in:
parent
a3afc9f7ce
commit
39a28ffe4e
@ -1507,7 +1507,34 @@ void ObjectMonitor::exit(JavaThread* current, bool not_suspended) {
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
assert(has_owner(current), "invariant");
|
||||
// If there is a successor we should release the lock as soon as
|
||||
// possible, so that the successor can acquire the lock. If there is
|
||||
// no successor, we might need to wake up a waiting thread.
|
||||
if (!has_successor()) {
|
||||
ObjectWaiter* w = Atomic::load(&_entry_list);
|
||||
if (w != nullptr) {
|
||||
// Other threads are blocked trying to acquire the lock and
|
||||
// there is no successor, so it appears that an heir-
|
||||
// presumptive (successor) must be made ready. Since threads
|
||||
// are woken up in FIFO order, we need to find the tail of the
|
||||
// entry_list.
|
||||
w = entry_list_tail(current);
|
||||
// I'd like to write: guarantee (w->_thread != current).
|
||||
// But in practice an exiting thread may find itself on the entry_list.
|
||||
// Let's say thread T1 calls O.wait(). Wait() enqueues T1 on O's waitset and
|
||||
// then calls exit(). Exit release the lock by setting O._owner to null.
|
||||
// Let's say T1 then stalls. T2 acquires O and calls O.notify(). The
|
||||
// notify() operation moves T1 from O's waitset to O's entry_list. T2 then
|
||||
// release the lock "O". T1 resumes immediately after the ST of null into
|
||||
// _owner, above. T1 notices that the entry_list is populated, so it
|
||||
// reacquires the lock and then finds itself on the entry_list.
|
||||
// Given all that, we have to tolerate the circumstance where "w" is
|
||||
// associated with current.
|
||||
assert(w->TState == ObjectWaiter::TS_ENTER, "invariant");
|
||||
exit_epilog(current, w);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Drop the lock.
|
||||
// release semantics: prior loads and stores from within the critical section
|
||||
@ -1547,11 +1574,9 @@ void ObjectMonitor::exit(JavaThread* current, bool not_suspended) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Other threads are blocked trying to acquire the lock and there
|
||||
// is no successor, so it appears that an heir-presumptive
|
||||
// (successor) must be made ready. Only the current lock owner can
|
||||
// detach threads from the entry_list, therefore we need to
|
||||
// reacquire the lock. If we fail to reacquire the lock the
|
||||
// Only the current lock owner can manipulate the entry_list
|
||||
// (except for pushing new threads to the head), therefore we need
|
||||
// to reacquire the lock. If we fail to reacquire the lock the
|
||||
// responsibility for ensuring succession falls to the new owner.
|
||||
|
||||
if (try_lock(current) != TryLockResult::Success) {
|
||||
@ -1561,27 +1586,6 @@ void ObjectMonitor::exit(JavaThread* current, bool not_suspended) {
|
||||
}
|
||||
|
||||
guarantee(has_owner(current), "invariant");
|
||||
|
||||
ObjectWaiter* w = nullptr;
|
||||
|
||||
w = Atomic::load(&_entry_list);
|
||||
if (w != nullptr) {
|
||||
w = entry_list_tail(current);
|
||||
// I'd like to write: guarantee (w->_thread != current).
|
||||
// But in practice an exiting thread may find itself on the entry_list.
|
||||
// Let's say thread T1 calls O.wait(). Wait() enqueues T1 on O's waitset and
|
||||
// then calls exit(). Exit release the lock by setting O._owner to null.
|
||||
// Let's say T1 then stalls. T2 acquires O and calls O.notify(). The
|
||||
// notify() operation moves T1 from O's waitset to O's entry_list. T2 then
|
||||
// release the lock "O". T1 resumes immediately after the ST of null into
|
||||
// _owner, above. T1 notices that the entry_list is populated, so it
|
||||
// reacquires the lock and then finds itself on the entry_list.
|
||||
// Given all that, we have to tolerate the circumstance where "w" is
|
||||
// associated with current.
|
||||
assert(w->TState == ObjectWaiter::TS_ENTER, "invariant");
|
||||
exit_epilog(current, w);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user