[K/N] Do not hold GC locks when finalizer thread is starting

Merge-request: KT-MR-9799
Merged-by: Alexander Shabalin <Alexander.Shabalin@jetbrains.com>
This commit is contained in:
Alexander Shabalin
2023-04-26 08:29:07 +00:00
committed by Space Team
parent c52ad22795
commit f058ee21b0
2 changed files with 11 additions and 5 deletions
@@ -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"
}
@@ -6,6 +6,7 @@
#include "ConcurrentMarkAndSweep.hpp"
#include <cinttypes>
#include <optional>
#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<SweepTraits>(gcHandle, extraObjectFactoryIterable);
auto finalizerQueue = gc::Sweep<SweepTraits>(gcHandle, objectFactoryIterable);
gc::SweepExtraObjects<SweepTraits>(gcHandle, *extraObjectFactoryIterable);
extraObjectFactoryIterable = std::nullopt;
auto finalizerQueue = gc::Sweep<SweepTraits>(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;
}