[K/N] Checked ManuallyScoped
Merge-request: KT-MR-14076
This commit is contained in:
committed by
Space Team
parent
5396a6f8da
commit
fb7176d5fa
@@ -49,9 +49,14 @@ public:
|
||||
mm::GlobalData::Instance().allocator().clearForTests();
|
||||
}
|
||||
|
||||
void initMutatorMarkQueue(mm::ThreadData& thread) {
|
||||
auto withMutatorQueue(mm::ThreadData& thread) {
|
||||
auto& markData = thread.gc().impl().gc().mark();
|
||||
markData.markQueue().construct(parProc_);
|
||||
return ScopeGuard{[&]{
|
||||
markData.markQueue().construct(parProc_);
|
||||
}, [&]{
|
||||
markData.markQueue()->clear();
|
||||
markData.markQueue().destroy();
|
||||
}};
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -62,7 +67,7 @@ private:
|
||||
|
||||
TEST_F(BarriersTest, Deletion) {
|
||||
RunInNewThread([this](mm::ThreadData& threadData) {
|
||||
initMutatorMarkQueue(threadData);
|
||||
auto queueScope = withMutatorQueue(threadData);
|
||||
auto& prevObj = AllocateObject(threadData);
|
||||
auto& newObj = AllocateObject(threadData);
|
||||
|
||||
@@ -93,7 +98,7 @@ TEST_F(BarriersTest, AllocationDuringMarkBarreirs) {
|
||||
gc::barriers::enableBarriers(gcHandle.getEpoch());
|
||||
|
||||
RunInNewThread([this](mm::ThreadData& threadData) {
|
||||
initMutatorMarkQueue(threadData);
|
||||
auto queueScope = withMutatorQueue(threadData);
|
||||
auto& obj = AllocateObject(threadData);
|
||||
EXPECT_THAT(gc::isMarked(obj.header()), true);
|
||||
});
|
||||
@@ -125,7 +130,7 @@ TEST_F(BarriersTest, ConcurrentDeletion) {
|
||||
threads.emplace_back([&]() noexcept {
|
||||
ScopedMemoryInit memory;
|
||||
mm::ThreadData& threadData = *memory.memoryState()->GetThreadData();
|
||||
initMutatorMarkQueue(threadData);
|
||||
auto queueScope = withMutatorQueue(threadData);
|
||||
|
||||
while (!canStart.load()) std::this_thread::yield();
|
||||
|
||||
|
||||
@@ -103,8 +103,8 @@ public:
|
||||
private:
|
||||
void ensureFlushActionExecuted() noexcept;
|
||||
|
||||
ManuallyScoped<MutatorQueue> markQueue_{};
|
||||
ManuallyScoped<OnceExecutable> flushAction_{};
|
||||
ManuallyScoped<MutatorQueue, true> markQueue_{};
|
||||
ManuallyScoped<OnceExecutable, true> flushAction_{};
|
||||
};
|
||||
|
||||
void beginMarkingEpoch(GCHandle gcHandle);
|
||||
@@ -139,7 +139,7 @@ private:
|
||||
|
||||
GCHandle gcHandle_ = GCHandle::invalid();
|
||||
std::optional<mm::ThreadRegistry::Iterable> lockedMutatorsList_;
|
||||
ManuallyScoped<ParallelProcessor> parallelProcessor_{};
|
||||
ManuallyScoped<ParallelProcessor, true> parallelProcessor_{};
|
||||
|
||||
RWSpinLock<MutexThreadStateHandling::kIgnore> markTerminationMutex_;
|
||||
};
|
||||
|
||||
@@ -174,7 +174,7 @@ private:
|
||||
GCHandle gcHandle_ = GCHandle::invalid();
|
||||
MarkPacer pacer_;
|
||||
std::optional<mm::ThreadRegistry::Iterable> lockedMutatorsList_;
|
||||
ManuallyScoped<ParallelProcessor> parallelProcessor_{};
|
||||
ManuallyScoped<ParallelProcessor, true> parallelProcessor_{};
|
||||
|
||||
std::mutex workerCreationMutex_;
|
||||
std::atomic<std::size_t> activeWorkersCount_ = 0;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
namespace kotlin {
|
||||
|
||||
// Like T but must be manually constructed and destroyed.
|
||||
template <typename T>
|
||||
template <typename T, bool kChecked = false>
|
||||
class ManuallyScoped : private Pinned {
|
||||
public:
|
||||
// Construct T
|
||||
@@ -37,4 +37,51 @@ private:
|
||||
alignas(T) char implStorage_[sizeof(T)];
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class ManuallyScoped<T, true> : private Pinned {
|
||||
public:
|
||||
ManuallyScoped() : constructed_(false) {}
|
||||
~ManuallyScoped() { assertDestroyed(); }
|
||||
|
||||
// Construct T
|
||||
template <typename... Args>
|
||||
void construct(Args&&... args) noexcept(noexcept(T(std::forward<Args>(args)...))) {
|
||||
assertDestroyed();
|
||||
impl_.construct(std::forward<Args>(args)...);
|
||||
constructed_ = true;
|
||||
}
|
||||
|
||||
// Destroy T
|
||||
void destroy() noexcept {
|
||||
assertConstructed();
|
||||
impl_.destroy();
|
||||
constructed_ = false;
|
||||
}
|
||||
|
||||
T& operator*() noexcept { return *impl(); }
|
||||
T* operator->() noexcept { return impl(); }
|
||||
const T& operator*() const noexcept { return *impl(); }
|
||||
const T* operator->() const noexcept { return impl(); }
|
||||
|
||||
private:
|
||||
T* impl() noexcept {
|
||||
assertConstructed();
|
||||
return &*impl_;
|
||||
}
|
||||
const T* impl() const noexcept {
|
||||
assertConstructed();
|
||||
return &*impl_;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE void assertConstructed() const noexcept {
|
||||
RuntimeAssert(constructed_, "ManuallyScoped value must have been constructed by this point");
|
||||
}
|
||||
ALWAYS_INLINE void assertDestroyed() const noexcept {
|
||||
RuntimeAssert(!constructed_, "ManuallyScoped value must have been destroyed by this point");
|
||||
}
|
||||
|
||||
bool constructed_;
|
||||
ManuallyScoped<T, false> impl_;
|
||||
};
|
||||
|
||||
} // namespace kotlin
|
||||
|
||||
Reference in New Issue
Block a user