52 static constexpr uint64_t
INACTIVE = UINT64_MAX;
111 if (ptr ==
nullptr) {
115 uint64_t epoch =
global_epoch_.load(std::memory_order_relaxed);
119 retired_[bucket].emplace_back(ptr, std::move(deleter));
133 delete static_cast<T*
>(p);
147 uint64_t current =
global_epoch_.fetch_add(1, std::memory_order_acq_rel);
155 uint64_t safe_epoch = current - 2;
162 std::vector<std::pair<
void*, std::function<void(
void*)>>> to_delete;
165 to_delete = std::move(
retired_[bucket]);
170 for (
auto& [ptr, deleter] : to_delete) {
174 gc_count_.fetch_add(1, std::memory_order_relaxed);
177 return to_delete.size();
191 std::vector<std::pair<
void*, std::function<void(
void*)>>> to_delete;
198 for (
auto& [ptr, deleter] : to_delete) {
201 total += to_delete.size();
205 gc_count_.fetch_add(1, std::memory_order_relaxed);
225 return gc_count_.load(std::memory_order_relaxed);
273 thread_local std::atomic<uint64_t> epoch{
INACTIVE};
RAII guard for epoch critical section.
~epoch_guard() noexcept
Exit critical section.
epoch_guard & operator=(epoch_guard &&)=delete
epoch_guard(epoch_guard &&)=delete
epoch_guard(const epoch_guard &)=delete
epoch_guard & operator=(const epoch_guard &)=delete
epoch_guard() noexcept
Enter critical section.
Epoch-based memory reclamation for lock-free data structures.
void defer_delete(T *ptr)
Defer deletion of a typed pointer.
std::array< std::vector< std::pair< void *, std::function< void(void *)> > >, NUM_EPOCHS > retired_
std::array< std::mutex, NUM_EPOCHS > retire_mutex_
size_t reclaimed_count() const noexcept
Get the total number of objects reclaimed.
void exit_critical() noexcept
Exit critical section.
std::atomic< uint64_t > global_epoch_
static std::atomic< uint64_t > & thread_epoch()
Get thread-local epoch reference.
size_t pending_count() const
Get the number of objects pending deletion.
static constexpr uint64_t INACTIVE
Sentinel value indicating thread is not in critical section.
size_t try_gc()
Attempt garbage collection.
std::atomic< size_t > reclaimed_count_
static constexpr size_t NUM_EPOCHS
Number of epochs in rotation (must be at least 3 for safety)
std::atomic< size_t > gc_count_
static epoch_manager & instance()
Get the singleton instance.
uint64_t current_epoch() const noexcept
Get the current global epoch.
void defer_delete(void *ptr, std::function< void(void *)> deleter)
Defer deletion of a pointer.
epoch_manager(epoch_manager &&)=delete
bool in_critical_section() const noexcept
Check if current thread is in critical section.
size_t gc_count() const noexcept
Get the number of GC cycles performed.
~epoch_manager()
Destructor - clean up any remaining deferred deletions.
epoch_manager()=default
Private constructor for singleton.
epoch_manager(const epoch_manager &)=delete
epoch_manager & operator=(epoch_manager &&)=delete
epoch_manager & operator=(const epoch_manager &)=delete
size_t force_gc()
Force garbage collection of all epochs.
void enter_critical() noexcept
Enter critical section (pin to current epoch)