From bd8ad309b59bceb3073a8d6411cca74e73508885 Mon Sep 17 00:00:00 2001 From: Xiaolong Peng Date: Fri, 21 Feb 2025 16:39:17 +0000 Subject: [PATCH] 8350285: Shenandoah: Regression caused by ShenandoahLock under extreme contention Reviewed-by: shade, kdnilsen --- .../share/gc/shenandoah/shenandoahLock.cpp | 19 ++++++++++++++++--- .../share/gc/shenandoah/shenandoahLock.hpp | 2 ++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp b/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp index be72127c6ec..47a144a638f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahLock.cpp @@ -45,6 +45,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) { @@ -67,17 +68,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 4d7eefd460c..0cef2414c0d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahLock.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahLock.hpp @@ -42,6 +42,8 @@ private: template void contended_lock_internal(JavaThread* java_thread); + static void yield_or_sleep(int &yields); + public: ShenandoahLock() : _state(unlocked), _owner(nullptr) {};