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:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user