diff --git a/kotlin-native/backend.native/tests/build.gradle b/kotlin-native/backend.native/tests/build.gradle index a727d189e3b..69fa5910230 100644 --- a/kotlin-native/backend.native/tests/build.gradle +++ b/kotlin-native/backend.native/tests/build.gradle @@ -972,7 +972,7 @@ task worker9_experimentalMM(type: KonanLocalTest) { task worker10(type: KonanLocalTest) { enabled = (project.testTarget != 'wasm32') && // Workers need pthreads. - !isNoopGC && !isAggressiveGC + !isNoopGC useGoldenData = true source = "runtime/workers/worker10.kt" } diff --git a/kotlin-native/runtime/src/gc/cms/cpp/ConcurrentMarkAndSweep.cpp b/kotlin-native/runtime/src/gc/cms/cpp/ConcurrentMarkAndSweep.cpp index 1a53554548e..0e24294f902 100644 --- a/kotlin-native/runtime/src/gc/cms/cpp/ConcurrentMarkAndSweep.cpp +++ b/kotlin-native/runtime/src/gc/cms/cpp/ConcurrentMarkAndSweep.cpp @@ -6,6 +6,7 @@ #include "ConcurrentMarkAndSweep.hpp" #include +#include #include "CompilerConstants.hpp" #include "GlobalData.hpp" @@ -194,13 +195,15 @@ bool gc::ConcurrentMarkAndSweep::PerformFullGC(int64_t epoch) noexcept { #ifndef CUSTOM_ALLOCATOR // Taking the locks before the pause is completed. So that any destroying thread // would not publish into the global state at an unexpected time. - auto extraObjectFactoryIterable = mm::GlobalData::Instance().extraObjectDataFactory().LockForIter(); - auto objectFactoryIterable = objectFactory_.LockForIter(); + std::optional extraObjectFactoryIterable = mm::GlobalData::Instance().extraObjectDataFactory().LockForIter(); + std::optional objectFactoryIterable = objectFactory_.LockForIter(); mm::ResumeThreads(); gcHandle.threadsAreResumed(); - gc::SweepExtraObjects(gcHandle, extraObjectFactoryIterable); - auto finalizerQueue = gc::Sweep(gcHandle, objectFactoryIterable); + gc::SweepExtraObjects(gcHandle, *extraObjectFactoryIterable); + extraObjectFactoryIterable = std::nullopt; + auto finalizerQueue = gc::Sweep(gcHandle, *objectFactoryIterable); + objectFactoryIterable = std::nullopt; kotlin::compactObjectPoolInMainThread(); #else auto finalizerQueue = heap_.SweepExtraObjects(gcHandle); @@ -212,6 +215,9 @@ bool gc::ConcurrentMarkAndSweep::PerformFullGC(int64_t epoch) noexcept { state_.finish(epoch); gcHandle.finalizersScheduled(finalizerQueue.size()); gcHandle.finished(); + // This may start a new thread. On some pthreads implementations, this may block waiting for concurrent thread + // destructors running. So, it must ensured that no locks are held by this point. + // TODO: Consider having an always on sleeping finalizer thread. finalizerProcessor_->ScheduleTasks(std::move(finalizerQueue), epoch); return true; }