[K/N] In CMS add a maximum number of iterations for queue flushing
^KT-79384
diff --git a/kotlin-native/runtime/src/gc/cms/cpp/ConcurrentMark.cpp b/kotlin-native/runtime/src/gc/cms/cpp/ConcurrentMark.cpp
index a81e641..820866c 100644
--- a/kotlin-native/runtime/src/gc/cms/cpp/ConcurrentMark.cpp
+++ b/kotlin-native/runtime/src/gc/cms/cpp/ConcurrentMark.cpp
@@ -145,7 +145,8 @@
std::unique_lock markTerminationGuard(markTerminationMutex_);
// has to happen under the termination lock guard
- flushMutatorQueues();
+ if (!flushMutatorQueues())
+ return false;
// After the mutators have been forced to flush their local queues,
// there is only on possibility for this counter to remain the same as on a previous iteration:
@@ -164,15 +165,18 @@
return true;
}
-void gc::mark::ConcurrentMark::flushMutatorQueues() noexcept {
+bool gc::mark::ConcurrentMark::flushMutatorQueues() noexcept {
for (auto& mutator : *lockedMutatorsList_) {
mutator.gc().impl().mark_.flushAction_.construct();
}
+ bool success = false;
{
FlushActionActivator flushActivator{};
// wait all mutators flushed
+ // TODO: How many iterations are actually needed?
+ size_t iterationCountLeft = 1000;
while (true) {
bool allDone = true;
for (auto& mutator : *lockedMutatorsList_) {
@@ -183,7 +187,12 @@
allDone = false;
}
}
- if (allDone) break;
+ if (allDone) {
+ success = true;
+ break;
+ }
+ if (--iterationCountLeft == 0)
+ break;
std::this_thread::yield();
}
}
@@ -192,6 +201,7 @@
for (auto& mutator : *lockedMutatorsList_) {
mutator.gc().impl().mark_.flushAction_.destroy();
}
+ return success;
}
void gc::mark::ConcurrentMark::resetMutatorFlags() {
diff --git a/kotlin-native/runtime/src/gc/cms/cpp/ConcurrentMark.hpp b/kotlin-native/runtime/src/gc/cms/cpp/ConcurrentMark.hpp
index 3c82481..48f1bde 100644
--- a/kotlin-native/runtime/src/gc/cms/cpp/ConcurrentMark.hpp
+++ b/kotlin-native/runtime/src/gc/cms/cpp/ConcurrentMark.hpp
@@ -147,7 +147,7 @@
void completeMutatorsRootSet(MarkTraits::MarkQueue& markQueue);
void tryCollectRootSet(mm::ThreadData& thread, ParallelProcessor::Worker& markQueue);
bool tryTerminateMark(std::size_t& everSharedBatches) noexcept;
- void flushMutatorQueues() noexcept;
+ bool flushMutatorQueues() noexcept;
void endMarkingEpoch();
void resetMutatorFlags();