diff --git a/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp b/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp index ee9559a3fb7..1d57c594dc0 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp @@ -46,6 +46,7 @@ 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) { @@ -68,17 +69,29 @@ void ShenandoahLock::contended_lock_internal(JavaThread* java_thread) { // VM thread to arm the poll sooner. while (SafepointSynchronize::is_synchronizing() && !SafepointMechanism::local_poll_armed(java_thread)) { - os::naked_yield(); + yield_or_sleep(yields); } } else { - os::naked_yield(); + yield_or_sleep(yields); } } else { - os::naked_yield(); + 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!"); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahLock.hpp b/src/hotspot/share/gc/shenandoah/shenandoahLock.hpp index 0d9206a4355..351731f5a25 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahLock.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahLock.hpp @@ -42,6 +42,8 @@ class ShenandoahLock { template void contended_lock_internal(JavaThread* java_thread); + static void yield_or_sleep(int &yields); + public: ShenandoahLock() : _state(unlocked), _owner(NULL) {};