< prev index next > src/hotspot/share/gc/shenandoah/shenandoahLock.cpp
Print this page
template<bool ALLOW_BLOCK>
void ShenandoahLock::contended_lock_internal(JavaThread* java_thread) {
assert(!ALLOW_BLOCK || java_thread != nullptr, "Must have a Java thread when allowing block.");
// Spin this much, but only on multi-processor systems.
int ctr = os::is_MP() ? 0xFF : 0;
+ int yields = 0;
// Apply TTAS to avoid more expensive CAS calls if the lock is still held by other thread.
while (Atomic::load(&_state) == locked ||
Atomic::cmpxchg(&_state, unlocked, locked) != unlocked) {
if (ctr > 0 && !SafepointSynchronize::is_synchronizing()) {
// Lightly contended, spin a little if no safepoint is pending.
// To avoid it, we wait here until local poll is armed and then proceed
// to TBVIM exit for blocking. We do not SpinPause, but yield to let
// VM thread to arm the poll sooner.
while (SafepointSynchronize::is_synchronizing() &&
!SafepointMechanism::local_poll_armed(java_thread)) {
! os::naked_yield();
}
} else {
! os::naked_yield();
}
} else {
! os::naked_yield();
}
}
}
ShenandoahSimpleLock::ShenandoahSimpleLock() {
assert(os::mutex_init_done(), "Too early!");
}
void ShenandoahSimpleLock::lock() {
// To avoid it, we wait here until local poll is armed and then proceed
// to TBVIM exit for blocking. We do not SpinPause, but yield to let
// VM thread to arm the poll sooner.
while (SafepointSynchronize::is_synchronizing() &&
!SafepointMechanism::local_poll_armed(java_thread)) {
! yield_or_sleep(yields);
}
} else {
! yield_or_sleep(yields);
}
} else {
! yield_or_sleep(yields);
}
}
}
+ void ShenandoahLock::yield_or_sleep(int &yields) {
+ // Simple yield-sleep policy: do one 100us sleep after every N yields.
+ // Tested with different values of N, and chose 3 for best performance.
+ if (yields < 3) {
+ os::naked_yield();
+ yields++;
+ } else {
+ os::naked_short_nanosleep(100000);
+ yields = 0;
+ }
+ }
+
ShenandoahSimpleLock::ShenandoahSimpleLock() {
assert(os::mutex_init_done(), "Too early!");
}
void ShenandoahSimpleLock::lock() {
< prev index next >