Add OnSuspendForGC hook to GCImpl::ThreadData

Co-authored-by: Johan Bay <jobay@google.com>

Merge-request: KOTLIN-MR-506
Merged-by: Alexander Shabalin <alexander.shabalin@jetbrains.com>
This commit is contained in:
Johan Bay
2022-09-16 14:43:54 +00:00
committed by Space
parent c8647841dc
commit 4b92d2e76c
9 changed files with 13 additions and 18 deletions
@@ -95,7 +95,7 @@ void gc::ConcurrentMarkAndSweep::ThreadData::OnOOM(size_t size) noexcept {
ScheduleAndWaitFullGC();
}
NO_EXTERNAL_CALLS_CHECK void gc::ConcurrentMarkAndSweep::ThreadData::PublishAndMark() noexcept {
NO_EXTERNAL_CALLS_CHECK void gc::ConcurrentMarkAndSweep::ThreadData::OnSuspendForGC() noexcept {
std::unique_lock lock(markingMutex);
if (!markingRequested.load())
return;
@@ -133,9 +133,6 @@ gc::ConcurrentMarkAndSweep::ConcurrentMarkAndSweep(
}
});
markingBehavior_ = kotlin::compiler::gcMarkSingleThreaded() ? MarkingBehavior::kDoNotMark : MarkingBehavior::kMarkOwnStack;
mm::SetOnSuspendCallback([](mm::ThreadData& thread) {
thread.gc().impl().gc().PublishAndMark();
});
RuntimeLogDebug({kTagGC}, "Concurrent Mark & Sweep GC initialized");
}
@@ -93,7 +93,7 @@ public:
void OnOOM(size_t size) noexcept;
void PublishAndMark() noexcept;
void OnSuspendForGC() noexcept;
Allocator CreateAllocator() noexcept { return Allocator(gc::Allocator(), *this); }
@@ -1176,7 +1176,7 @@ TEST_P(ConcurrentMarkAndSweepTest, MutatorsCanMarkOwnLocals) {
for (int i = 0; i < kDefaultThreadCount; ++i) {
gcFutures[i] = mutators[i]
.Execute([](mm::ThreadData& threadData, Mutator& mutator) { threadData.gc().impl().gc().PublishAndMark(); });
.Execute([](mm::ThreadData& threadData, Mutator& mutator) { threadData.gc().impl().gc().OnSuspendForGC(); });
}
if (GetParam() == gc::ConcurrentMarkAndSweep::kMarkOwnStack) {
@@ -60,6 +60,10 @@ void gc::GC::ThreadData::OnStoppedForGC() noexcept {
impl_->gcScheduler().OnStoppedForGC();
}
void gc::GC::ThreadData::OnSuspendForGC() noexcept {
impl_->gc().OnSuspendForGC();
}
gc::GC::GC() noexcept : impl_(std_support::make_unique<Impl>()) {}
gc::GC::~GC() = default;
@@ -45,6 +45,7 @@ public:
ArrayHeader* CreateArray(const TypeInfo* typeInfo, uint32_t elements) noexcept;
void OnStoppedForGC() noexcept;
void OnSuspendForGC() noexcept;
private:
std_support::unique_ptr<Impl> impl_;
@@ -50,6 +50,8 @@ void gc::GC::ThreadData::OnStoppedForGC() noexcept {
impl_->gcScheduler().OnStoppedForGC();
}
void gc::GC::ThreadData::OnSuspendForGC() noexcept { }
gc::GC::GC() noexcept : impl_(std_support::make_unique<Impl>()) {}
gc::GC::~GC() = default;
@@ -62,6 +62,8 @@ void gc::GC::ThreadData::OnStoppedForGC() noexcept {
impl_->gcScheduler().OnStoppedForGC();
}
void gc::GC::ThreadData::OnSuspendForGC() noexcept { }
gc::GC::GC() noexcept : impl_(std_support::make_unique<Impl>()) {}
gc::GC::~GC() = default;
@@ -45,7 +45,6 @@ void yield() noexcept {
THREAD_LOCAL_VARIABLE bool gSuspensionRequestedByCurrentThread = false;
[[clang::no_destroy]] std::mutex gSuspensionMutex;
[[clang::no_destroy]] std::condition_variable gSuspensionCondVar;
[[clang::no_destroy]] std::function<void(kotlin::mm::ThreadData&)> gPreSuspend = nullptr;
} // namespace
@@ -53,8 +52,7 @@ std::atomic<bool> kotlin::mm::internal::gSuspensionRequested = false;
NO_EXTERNAL_CALLS_CHECK void kotlin::mm::ThreadSuspensionData::suspendIfRequestedSlowPath() noexcept {
if (IsThreadSuspensionRequested()) {
if (gPreSuspend)
gPreSuspend(threadData_);
threadData_.gc().OnSuspendForGC();
std::unique_lock lock(gSuspensionMutex);
auto threadId = konan::currentThreadId();
auto suspendStartMs = konan::getTimeMicros();
@@ -99,10 +97,6 @@ ALWAYS_INLINE void kotlin::mm::SuspendIfRequested() noexcept {
}
}
void kotlin::mm::SetOnSuspendCallback(std::function<void(mm::ThreadData&)> preSuspend) noexcept {
gPreSuspend = preSuspend;
}
void kotlin::mm::ResumeThreads() noexcept {
// From the std::condition_variable docs:
// Even if the shared variable is atomic, it must be modified under
@@ -78,11 +78,6 @@ inline bool SuspendThreads() noexcept {
return true;
}
/**
* Set function `preSuspend` which will be called in threads before suspending.
*/
void SetOnSuspendCallback(std::function<void(mm::ThreadData&)>) noexcept;
/**
* Resumes all threads registered in ThreadRegistry that were suspended by the SuspendThreads call.
* Does not wait until all such threads are actually resumed.