From 523e9495fc763e5924ad6e0b140ae88e0e4afe9b Mon Sep 17 00:00:00 2001 From: Pavel Kunyavskiy Date: Tue, 17 Aug 2021 10:08:40 +0300 Subject: [PATCH] [K/N] Optimize safepoint implementation --- .../gc/stms/cpp/SameThreadMarkAndSweep.cpp | 21 ++++++++++++------- .../gc/stms/cpp/SameThreadMarkAndSweep.hpp | 1 + .../runtime/src/mm/cpp/ThreadSuspension.cpp | 17 +++++++++------ .../runtime/src/mm/cpp/ThreadSuspension.hpp | 1 + 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/kotlin-native/runtime/src/gc/stms/cpp/SameThreadMarkAndSweep.cpp b/kotlin-native/runtime/src/gc/stms/cpp/SameThreadMarkAndSweep.cpp index 52162c236b2..5e32a10944d 100644 --- a/kotlin-native/runtime/src/gc/stms/cpp/SameThreadMarkAndSweep.cpp +++ b/kotlin-native/runtime/src/gc/stms/cpp/SameThreadMarkAndSweep.cpp @@ -99,16 +99,23 @@ void gc::SameThreadMarkAndSweep::ThreadData::OnOOM(size_t size) noexcept { PerformFullGC(); } -void gc::SameThreadMarkAndSweep::ThreadData::SafePointRegular(size_t weight) noexcept { - size_t counterOverhead = gc_.GetThreshold() == 0 ? safePointsCounter_ : safePointsCounter_ % gc_.GetThreshold(); - if (threadData_.suspensionData().suspendIfRequested()) { - safePointsCounter_ = 0; - } else if (counterOverhead + weight >= gc_.GetThreshold() && konan::getTimeMicros() - timeOfLastGcUs_ >= gc_.GetCooldownThresholdUs()) { +void gc::SameThreadMarkAndSweep::ThreadData::SafePointRegularSlowPath() noexcept { + safePointsCounter_ = 0; + if (konan::getTimeMicros() - timeOfLastGcUs_ >= gc_.GetCooldownThresholdUs()) { timeOfLastGcUs_ = konan::getTimeMicros(); - safePointsCounter_ = 0; PerformFullGC(); } - safePointsCounter_ += weight; +} + +void gc::SameThreadMarkAndSweep::ThreadData::SafePointRegular(size_t weight) noexcept { + if (threadData_.suspensionData().suspendIfRequested()) { + safePointsCounter_ = 0; + } else { + safePointsCounter_ += weight; + if (safePointsCounter_ >= gc_.GetThreshold()) { + SafePointRegularSlowPath(); + } + } } gc::SameThreadMarkAndSweep::SameThreadMarkAndSweep() noexcept { diff --git a/kotlin-native/runtime/src/gc/stms/cpp/SameThreadMarkAndSweep.hpp b/kotlin-native/runtime/src/gc/stms/cpp/SameThreadMarkAndSweep.hpp index 7af6898523d..f8f83b40770 100644 --- a/kotlin-native/runtime/src/gc/stms/cpp/SameThreadMarkAndSweep.hpp +++ b/kotlin-native/runtime/src/gc/stms/cpp/SameThreadMarkAndSweep.hpp @@ -56,6 +56,7 @@ public: private: void SafePointRegular(size_t weight) noexcept; + void SafePointRegularSlowPath() noexcept; SameThreadMarkAndSweep& gc_; mm::ThreadData& threadData_; diff --git a/kotlin-native/runtime/src/mm/cpp/ThreadSuspension.cpp b/kotlin-native/runtime/src/mm/cpp/ThreadSuspension.cpp index 1d3cc90c266..e3ef95ca275 100644 --- a/kotlin-native/runtime/src/mm/cpp/ThreadSuspension.cpp +++ b/kotlin-native/runtime/src/mm/cpp/ThreadSuspension.cpp @@ -46,12 +46,17 @@ std::condition_variable gSuspendsionCondVar; NO_EXTERNAL_CALLS_CHECK bool kotlin::mm::ThreadSuspensionData::suspendIfRequested() noexcept { if (IsThreadSuspensionRequested()) { - std::unique_lock lock(gSuspensionMutex); - if (IsThreadSuspensionRequested()) { - AutoReset scopedAssign(&suspended_, true); - gSuspendsionCondVar.wait(lock, []() { return !IsThreadSuspensionRequested(); }); - return true; - } + return suspendIfRequestedSlowPath(); + } + return false; +} + +NO_EXTERNAL_CALLS_CHECK bool kotlin::mm::ThreadSuspensionData::suspendIfRequestedSlowPath() noexcept { + std::unique_lock lock(gSuspensionMutex); + if (IsThreadSuspensionRequested()) { + AutoReset scopedAssign(&suspended_, true); + gSuspendsionCondVar.wait(lock, []() { return !IsThreadSuspensionRequested(); }); + return true; } return false; } diff --git a/kotlin-native/runtime/src/mm/cpp/ThreadSuspension.hpp b/kotlin-native/runtime/src/mm/cpp/ThreadSuspension.hpp index f55018e77f8..f2c52e6832c 100644 --- a/kotlin-native/runtime/src/mm/cpp/ThreadSuspension.hpp +++ b/kotlin-native/runtime/src/mm/cpp/ThreadSuspension.hpp @@ -36,6 +36,7 @@ public: private: std::atomic state_; std::atomic suspended_; + bool suspendIfRequestedSlowPath() noexcept; }; bool IsThreadSuspensionRequested() noexcept;