From 35612201f988fafd3495951a2885439ac62427e1 Mon Sep 17 00:00:00 2001 From: LoveSy Date: Tue, 27 Jun 2023 15:31:44 +0800 Subject: [PATCH] Lock-free JavaDebuggable guard --- lsplant/src/main/jni/lsplant.cc | 48 +++++++++++++++++++++++++++------ 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/lsplant/src/main/jni/lsplant.cc b/lsplant/src/main/jni/lsplant.cc index a77303b..81338b2 100644 --- a/lsplant/src/main/jni/lsplant.cc +++ b/lsplant/src/main/jni/lsplant.cc @@ -615,22 +615,54 @@ std::string GetProxyMethodShorty(JNIEnv *env, jobject proxy_method) { struct JavaDebuggableGuard { JavaDebuggableGuard() { - std::unique_lock lk(lock); - if (count.fetch_add(1, std::memory_order_acq_rel) == 0) { - Runtime::Current()->SetJavaDebuggable( - Runtime::RuntimeDebugState::kJavaDebuggableAtInit); + while (true) { + size_t expected = 0; + if (count.compare_exchange_strong(expected, 1, std::memory_order_acq_rel, + std::memory_order_acquire)) { + Runtime::Current()->SetJavaDebuggable( + Runtime::RuntimeDebugState::kJavaDebuggableAtInit); + count.fetch_add(1, std::memory_order_release); + count.notify_all(); + break; + } + if (expected == 1) { + count.wait(expected, std::memory_order_acquire); + continue; + } + if (count.compare_exchange_strong(expected, expected + 1, std::memory_order_acq_rel, + std::memory_order_relaxed)) { + break; + } } } ~JavaDebuggableGuard() { - std::unique_lock lk(lock); - if (count.fetch_sub(1, std::memory_order_acq_rel) == 1) { - Runtime::Current()->SetJavaDebuggable(Runtime::RuntimeDebugState::kNonJavaDebuggable); + while (true) { + size_t expected = 2; + if (count.compare_exchange_strong(expected, 1, std::memory_order_acq_rel, + std::memory_order_acquire)) { + Runtime::Current()->SetJavaDebuggable( + Runtime::RuntimeDebugState::kNonJavaDebuggable); + count.fetch_sub(1, std::memory_order_release); + count.notify_all(); + break; + } + if (expected == 1) { + count.wait(expected, std::memory_order_acquire); + continue; + } + if (count.compare_exchange_strong(expected, expected - 1, std::memory_order_acq_rel, + std::memory_order_relaxed)) { + break; + } } } +private: inline static std::atomic_size_t count{0}; - inline static std::mutex lock; + static_assert(std::atomic_size_t::is_always_lock_free, "Unsupported architecture"); + static_assert(std::is_same_v, + "Unsupported architecture"); }; } // namespace