[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();
|
mm::GlobalData::Instance().allocator().clearForTests();
|
||||||
}
|
}
|
||||||
|
|
||||||
void initMutatorMarkQueue(mm::ThreadData& thread) {
|
auto withMutatorQueue(mm::ThreadData& thread) {
|
||||||
auto& markData = thread.gc().impl().gc().mark();
|
auto& markData = thread.gc().impl().gc().mark();
|
||||||
markData.markQueue().construct(parProc_);
|
return ScopeGuard{[&]{
|
||||||
|
markData.markQueue().construct(parProc_);
|
||||||
|
}, [&]{
|
||||||
|
markData.markQueue()->clear();
|
||||||
|
markData.markQueue().destroy();
|
||||||
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -62,7 +67,7 @@ private:
|
|||||||
|
|
||||||
TEST_F(BarriersTest, Deletion) {
|
TEST_F(BarriersTest, Deletion) {
|
||||||
RunInNewThread([this](mm::ThreadData& threadData) {
|
RunInNewThread([this](mm::ThreadData& threadData) {
|
||||||
initMutatorMarkQueue(threadData);
|
auto queueScope = withMutatorQueue(threadData);
|
||||||
auto& prevObj = AllocateObject(threadData);
|
auto& prevObj = AllocateObject(threadData);
|
||||||
auto& newObj = AllocateObject(threadData);
|
auto& newObj = AllocateObject(threadData);
|
||||||
|
|
||||||
@@ -93,7 +98,7 @@ TEST_F(BarriersTest, AllocationDuringMarkBarreirs) {
|
|||||||
gc::barriers::enableBarriers(gcHandle.getEpoch());
|
gc::barriers::enableBarriers(gcHandle.getEpoch());
|
||||||
|
|
||||||
RunInNewThread([this](mm::ThreadData& threadData) {
|
RunInNewThread([this](mm::ThreadData& threadData) {
|
||||||
initMutatorMarkQueue(threadData);
|
auto queueScope = withMutatorQueue(threadData);
|
||||||
auto& obj = AllocateObject(threadData);
|
auto& obj = AllocateObject(threadData);
|
||||||
EXPECT_THAT(gc::isMarked(obj.header()), true);
|
EXPECT_THAT(gc::isMarked(obj.header()), true);
|
||||||
});
|
});
|
||||||
@@ -125,7 +130,7 @@ TEST_F(BarriersTest, ConcurrentDeletion) {
|
|||||||
threads.emplace_back([&]() noexcept {
|
threads.emplace_back([&]() noexcept {
|
||||||
ScopedMemoryInit memory;
|
ScopedMemoryInit memory;
|
||||||
mm::ThreadData& threadData = *memory.memoryState()->GetThreadData();
|
mm::ThreadData& threadData = *memory.memoryState()->GetThreadData();
|
||||||
initMutatorMarkQueue(threadData);
|
auto queueScope = withMutatorQueue(threadData);
|
||||||
|
|
||||||
while (!canStart.load()) std::this_thread::yield();
|
while (!canStart.load()) std::this_thread::yield();
|
||||||
|
|
||||||
|
|||||||
@@ -103,8 +103,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
void ensureFlushActionExecuted() noexcept;
|
void ensureFlushActionExecuted() noexcept;
|
||||||
|
|
||||||
ManuallyScoped<MutatorQueue> markQueue_{};
|
ManuallyScoped<MutatorQueue, true> markQueue_{};
|
||||||
ManuallyScoped<OnceExecutable> flushAction_{};
|
ManuallyScoped<OnceExecutable, true> flushAction_{};
|
||||||
};
|
};
|
||||||
|
|
||||||
void beginMarkingEpoch(GCHandle gcHandle);
|
void beginMarkingEpoch(GCHandle gcHandle);
|
||||||
@@ -139,7 +139,7 @@ private:
|
|||||||
|
|
||||||
GCHandle gcHandle_ = GCHandle::invalid();
|
GCHandle gcHandle_ = GCHandle::invalid();
|
||||||
std::optional<mm::ThreadRegistry::Iterable> lockedMutatorsList_;
|
std::optional<mm::ThreadRegistry::Iterable> lockedMutatorsList_;
|
||||||
ManuallyScoped<ParallelProcessor> parallelProcessor_{};
|
ManuallyScoped<ParallelProcessor, true> parallelProcessor_{};
|
||||||
|
|
||||||
RWSpinLock<MutexThreadStateHandling::kIgnore> markTerminationMutex_;
|
RWSpinLock<MutexThreadStateHandling::kIgnore> markTerminationMutex_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ private:
|
|||||||
GCHandle gcHandle_ = GCHandle::invalid();
|
GCHandle gcHandle_ = GCHandle::invalid();
|
||||||
MarkPacer pacer_;
|
MarkPacer pacer_;
|
||||||
std::optional<mm::ThreadRegistry::Iterable> lockedMutatorsList_;
|
std::optional<mm::ThreadRegistry::Iterable> lockedMutatorsList_;
|
||||||
ManuallyScoped<ParallelProcessor> parallelProcessor_{};
|
ManuallyScoped<ParallelProcessor, true> parallelProcessor_{};
|
||||||
|
|
||||||
std::mutex workerCreationMutex_;
|
std::mutex workerCreationMutex_;
|
||||||
std::atomic<std::size_t> activeWorkersCount_ = 0;
|
std::atomic<std::size_t> activeWorkersCount_ = 0;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
namespace kotlin {
|
namespace kotlin {
|
||||||
|
|
||||||
// Like T but must be manually constructed and destroyed.
|
// Like T but must be manually constructed and destroyed.
|
||||||
template <typename T>
|
template <typename T, bool kChecked = false>
|
||||||
class ManuallyScoped : private Pinned {
|
class ManuallyScoped : private Pinned {
|
||||||
public:
|
public:
|
||||||
// Construct T
|
// Construct T
|
||||||
@@ -37,4 +37,51 @@ private:
|
|||||||
alignas(T) char implStorage_[sizeof(T)];
|
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
|
} // namespace kotlin
|
||||||
|
|||||||
Reference in New Issue
Block a user