[K/N] Simplify safepoint slowpath in CMS
^KT-50291 Merge-request: KT-MR-5263
This commit is contained in:
committed by
Space
parent
8b23d86bd9
commit
8863d48595
@@ -57,8 +57,6 @@ struct SweepTraits {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Global, because it's accessed on a hot path: avoid memory load from `this`.
|
|
||||||
std::atomic<bool> gNeedSafepointSlowpath = false;
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
ALWAYS_INLINE void gc::ConcurrentMarkAndSweep::ThreadData::SafePointFunctionPrologue() noexcept {
|
ALWAYS_INLINE void gc::ConcurrentMarkAndSweep::ThreadData::SafePointFunctionPrologue() noexcept {
|
||||||
@@ -71,9 +69,7 @@ ALWAYS_INLINE void gc::ConcurrentMarkAndSweep::ThreadData::SafePointLoopBody() n
|
|||||||
|
|
||||||
void gc::ConcurrentMarkAndSweep::ThreadData::SafePointAllocation(size_t size) noexcept {
|
void gc::ConcurrentMarkAndSweep::ThreadData::SafePointAllocation(size_t size) noexcept {
|
||||||
threadData_.gcScheduler().OnSafePointAllocation(size);
|
threadData_.gcScheduler().OnSafePointAllocation(size);
|
||||||
if (gNeedSafepointSlowpath.load()) {
|
mm::SuspendIfRequested();
|
||||||
SafePointSlowPath();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void gc::ConcurrentMarkAndSweep::ThreadData::ScheduleAndWaitFullGC() noexcept {
|
void gc::ConcurrentMarkAndSweep::ThreadData::ScheduleAndWaitFullGC() noexcept {
|
||||||
ThreadStateGuard guard(ThreadState::kNative);
|
ThreadStateGuard guard(ThreadState::kNative);
|
||||||
@@ -98,13 +94,7 @@ void gc::ConcurrentMarkAndSweep::ThreadData::OnOOM(size_t size) noexcept {
|
|||||||
|
|
||||||
ALWAYS_INLINE void gc::ConcurrentMarkAndSweep::ThreadData::SafePointRegular(size_t weight) noexcept {
|
ALWAYS_INLINE void gc::ConcurrentMarkAndSweep::ThreadData::SafePointRegular(size_t weight) noexcept {
|
||||||
threadData_.gcScheduler().OnSafePointRegular(weight);
|
threadData_.gcScheduler().OnSafePointRegular(weight);
|
||||||
if (gNeedSafepointSlowpath.load()) {
|
mm::SuspendIfRequested();
|
||||||
SafePointSlowPath();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NO_EXTERNAL_CALLS_CHECK NO_INLINE void gc::ConcurrentMarkAndSweep::ThreadData::SafePointSlowPath() noexcept {
|
|
||||||
threadData_.suspensionData().suspendIfRequested();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gc::ConcurrentMarkAndSweep::ConcurrentMarkAndSweep() noexcept :
|
gc::ConcurrentMarkAndSweep::ConcurrentMarkAndSweep() noexcept :
|
||||||
@@ -131,22 +121,11 @@ gc::ConcurrentMarkAndSweep::~ConcurrentMarkAndSweep() {
|
|||||||
gcThread_.join();
|
gcThread_.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void gc::ConcurrentMarkAndSweep::RequestThreadsSuspension() noexcept {
|
|
||||||
gNeedSafepointSlowpath = true;
|
|
||||||
bool didSuspend = mm::RequestThreadsSuspension();
|
|
||||||
RuntimeAssert(didSuspend, "Only GC thread can request suspension");
|
|
||||||
}
|
|
||||||
|
|
||||||
void gc::ConcurrentMarkAndSweep::ResumeThreads() noexcept {
|
|
||||||
mm::ResumeThreads();
|
|
||||||
gNeedSafepointSlowpath = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool gc::ConcurrentMarkAndSweep::PerformFullGC(int64_t epoch) noexcept {
|
bool gc::ConcurrentMarkAndSweep::PerformFullGC(int64_t epoch) noexcept {
|
||||||
RuntimeLogDebug({kTagGC}, "Attempt to suspend threads by thread %d", konan::currentThreadId());
|
RuntimeLogDebug({kTagGC}, "Attempt to suspend threads by thread %d", konan::currentThreadId());
|
||||||
auto timeStartUs = konan::getTimeMicros();
|
auto timeStartUs = konan::getTimeMicros();
|
||||||
RequestThreadsSuspension();
|
bool didSuspend = mm::RequestThreadsSuspension();
|
||||||
|
RuntimeAssert(didSuspend, "Only GC thread can request suspension");
|
||||||
RuntimeLogDebug({kTagGC}, "Requested thread suspension by thread %d", konan::currentThreadId());
|
RuntimeLogDebug({kTagGC}, "Requested thread suspension by thread %d", konan::currentThreadId());
|
||||||
|
|
||||||
RuntimeAssert(!kotlin::mm::IsCurrentThreadRegistered(), "Concurrent GC must run on unregistered thread");
|
RuntimeAssert(!kotlin::mm::IsCurrentThreadRegistered(), "Concurrent GC must run on unregistered thread");
|
||||||
@@ -179,7 +158,7 @@ bool gc::ConcurrentMarkAndSweep::PerformFullGC(int64_t epoch) noexcept {
|
|||||||
|
|
||||||
auto objectFactoryIterable = mm::GlobalData::Instance().objectFactory().LockForIter();
|
auto objectFactoryIterable = mm::GlobalData::Instance().objectFactory().LockForIter();
|
||||||
|
|
||||||
ResumeThreads();
|
mm::ResumeThreads();
|
||||||
auto timeResumeUs = konan::getTimeMicros();
|
auto timeResumeUs = konan::getTimeMicros();
|
||||||
|
|
||||||
RuntimeLogDebug({kTagGC},
|
RuntimeLogDebug({kTagGC},
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void SafePointRegular(size_t weight) noexcept;
|
void SafePointRegular(size_t weight) noexcept;
|
||||||
void SafePointSlowPath() noexcept;
|
|
||||||
|
|
||||||
ConcurrentMarkAndSweep& gc_;
|
ConcurrentMarkAndSweep& gc_;
|
||||||
mm::ThreadData& threadData_;
|
mm::ThreadData& threadData_;
|
||||||
@@ -81,8 +80,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
// Returns `true` if GC has happened, and `false` if not (because someone else has suspended the threads).
|
// Returns `true` if GC has happened, and `false` if not (because someone else has suspended the threads).
|
||||||
bool PerformFullGC(int64_t epoch) noexcept;
|
bool PerformFullGC(int64_t epoch) noexcept;
|
||||||
void RequestThreadsSuspension() noexcept;
|
|
||||||
void ResumeThreads() noexcept;
|
|
||||||
|
|
||||||
uint64_t lastGCTimestampUs_ = 0;
|
uint64_t lastGCTimestampUs_ = 0;
|
||||||
GCStateHolder state_;
|
GCStateHolder state_;
|
||||||
|
|||||||
@@ -86,6 +86,12 @@ void kotlin::mm::WaitForThreadsSuspension() noexcept {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALWAYS_INLINE void kotlin::mm::SuspendIfRequested() noexcept {
|
||||||
|
if (IsThreadSuspensionRequested()) {
|
||||||
|
mm::ThreadRegistry::Instance().CurrentThreadData()->suspensionData().suspendIfRequestedSlowPath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void kotlin::mm::ResumeThreads() noexcept {
|
void kotlin::mm::ResumeThreads() noexcept {
|
||||||
// From the std::condition_variable docs:
|
// From the std::condition_variable docs:
|
||||||
// Even if the shared variable is atomic, it must be modified under
|
// Even if the shared variable is atomic, it must be modified under
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend void SuspendIfRequested() noexcept;
|
||||||
|
|
||||||
std::atomic<ThreadState> state_;
|
std::atomic<ThreadState> state_;
|
||||||
std::atomic<bool> suspended_;
|
std::atomic<bool> suspended_;
|
||||||
void suspendIfRequestedSlowPath() noexcept;
|
void suspendIfRequestedSlowPath() noexcept;
|
||||||
@@ -56,6 +58,7 @@ private:
|
|||||||
|
|
||||||
bool RequestThreadsSuspension() noexcept;
|
bool RequestThreadsSuspension() noexcept;
|
||||||
void WaitForThreadsSuspension() noexcept;
|
void WaitForThreadsSuspension() noexcept;
|
||||||
|
void SuspendIfRequested() noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Suspends all threads registered in ThreadRegistry except threads that are in the Native state.
|
* Suspends all threads registered in ThreadRegistry except threads that are in the Native state.
|
||||||
|
|||||||
Reference in New Issue
Block a user