diff --git a/src/mem/globalalloc.h b/src/mem/globalalloc.h index c44de93..cc4ecd5 100644 --- a/src/mem/globalalloc.h +++ b/src/mem/globalalloc.h @@ -11,7 +11,7 @@ namespace snmalloc static_assert( SharedStateHandle::Options.CoreAllocIsPoolAllocated, "Global statistics are available only for pool-allocated configurations"); - auto* alloc = AllocPool>::template iterate< + auto* alloc = Pool>::template iterate< SharedStateHandle>(); while (alloc != nullptr) @@ -20,7 +20,7 @@ namespace snmalloc if (a != nullptr) stats.add(*a); stats.add(alloc->stats()); - alloc = AllocPool>::template iterate< + alloc = Pool>::template iterate< SharedStateHandle>(alloc); } } @@ -32,7 +32,7 @@ namespace snmalloc static_assert( SharedStateHandle::Options.CoreAllocIsPoolAllocated, "Global statistics are available only for pool-allocated configurations"); - auto alloc = AllocPool>::template iterate< + auto alloc = Pool>::template iterate< SharedStateHandle>(); while (alloc != nullptr) @@ -40,7 +40,7 @@ namespace snmalloc auto stats = alloc->stats(); if (stats != nullptr) stats->template print(o, dumpid, alloc->id()); - alloc = AllocPool>::template iterate< + alloc = Pool>::template iterate< SharedStateHandle>(alloc); } } @@ -64,7 +64,7 @@ namespace snmalloc // allocators that are not currently in use by any thread. // One atomic operation to extract the stack, another to restore it. // Handling the message queue for each stack is non-atomic. - auto* first = AllocPool>::extract(); + auto* first = Pool>::extract(); auto* alloc = first; decltype(alloc) last; @@ -74,10 +74,10 @@ namespace snmalloc { alloc->flush(); last = alloc; - alloc = AllocPool>::extract(alloc); + alloc = Pool>::extract(alloc); } - AllocPool>::restore(first, last); + Pool>::restore(first, last); } #endif } @@ -96,7 +96,7 @@ namespace snmalloc "Global status is available only for pool-allocated configurations"); // This is a debugging function. It checks that all memory from all // allocators has been freed. - auto* alloc = AllocPool>::template iterate< + auto* alloc = Pool>::template iterate< SharedStateHandle>(); # ifdef SNMALLOC_TRACING @@ -111,7 +111,7 @@ namespace snmalloc std::cout << "debug_check_empty: Check all allocators!" << std::endl; # endif done = true; - alloc = AllocPool>::template iterate< + alloc = Pool>::template iterate< SharedStateHandle>(); okay = true; @@ -134,7 +134,7 @@ namespace snmalloc # ifdef SNMALLOC_TRACING std::cout << "debug check empty: okay = " << okay << std::endl; # endif - alloc = AllocPool>::template iterate< + alloc = Pool>::template iterate< SharedStateHandle>(alloc); } } @@ -148,12 +148,12 @@ namespace snmalloc // Redo check so abort is on allocator with allocation left. if (!okay) { - alloc = AllocPool>::template iterate< + alloc = Pool>::template iterate< SharedStateHandle>(); while (alloc != nullptr) { alloc->debug_is_empty(nullptr); - alloc = AllocPool>::template iterate< + alloc = Pool>::template iterate< SharedStateHandle>(alloc); } } @@ -168,7 +168,7 @@ namespace snmalloc static_assert( SharedStateHandle::Options.CoreAllocIsPoolAllocated, "Global status is available only for pool-allocated configurations"); - auto alloc = AllocPool>::template iterate< + auto alloc = Pool>::template iterate< SharedStateHandle>(); while (alloc != nullptr) { @@ -180,7 +180,7 @@ namespace snmalloc } count--; } - alloc = AllocPool>::template iterate< + alloc = Pool>::template iterate< SharedStateHandle>(alloc); if (count != 0) diff --git a/src/mem/localalloc.h b/src/mem/localalloc.h index 19a5b9c..7b1c912 100644 --- a/src/mem/localalloc.h +++ b/src/mem/localalloc.h @@ -380,7 +380,7 @@ namespace snmalloc // Initialise the global allocator structures ensure_init(); // Grab an allocator for this thread. - init(AllocPool::template acquire( + init(Pool::template acquire( &(this->local_cache))); } @@ -403,7 +403,7 @@ namespace snmalloc // Return underlying allocator to the system. if constexpr (SharedStateHandle::Options.CoreAllocOwnsLocalState) { - AllocPool::template release(core_alloc); + Pool::template release(core_alloc); } // Set up thread local allocator to look like diff --git a/src/mem/pool.h b/src/mem/pool.h index 2b0c177..990c849 100644 --- a/src/mem/pool.h +++ b/src/mem/pool.h @@ -21,10 +21,8 @@ namespace snmalloc template class PoolState { - template - friend class Pool; template - friend class AllocPool; + friend class Pool; private: std::atomic_flag lock = ATOMIC_FLAG_INIT; @@ -35,90 +33,30 @@ namespace snmalloc constexpr PoolState() = default; }; + /** + * Class used to instantiate non-allocator pools using a Singleton PoolState. + */ template - class Pool + class PoolStateHandle { - PoolState state; + static PoolState& pool_state = + Singleton, PoolStateHandle::make_state>::get(); + + static PoolState* make_state() + { + return ChunkAllocator::alloc_meta_data, SharedStateHandle>( + nullptr); + } public: - static Pool* make() noexcept + static PoolState& pool() { - return ChunkAllocator::alloc_meta_data(nullptr); - } - - template - T* acquire(Args&&... args) - { - T* p = state.stack.pop(); - - if (p != nullptr) - { - p->set_in_use(); - return p; - } - - p = ChunkAllocator::alloc_meta_data( - nullptr, std::forward(args)...); - - FlagLock f(state.lock); - p->list_next = state.list; - state.list = p; - - p->set_in_use(); - return p; - } - - /** - * Return to the pool an object previously retrieved by `acquire` - * - * Do not return objects from `extract`. - */ - void release(T* p) - { - // The object's destructor is not run. If the object is "reallocated", it - // is returned without the constructor being run, so the object is reused - // without re-initialisation. - p->reset_in_use(); - state.stack.push(p); - } - - T* extract(T* p = nullptr) - { - // Returns a linked list of all objects in the stack, emptying the stack. - if (p == nullptr) - return state.stack.pop_all(); - - return p->next; - } - - /** - * Return to the pool a list of object previously retrieved by `extract` - * - * Do not return objects from `acquire`. - */ - void restore(T* first, T* last) - { - // Pushes a linked list of objects onto the stack. Use to put a linked - // list returned by extract back onto the stack. - state.stack.push(first, last); - } - - T* iterate(T* p = nullptr) - { - if (p == nullptr) - return state.list; - - return p->list_next; + return pool_state; } }; - /** - * Collection of static wrappers for the allocator pool. - * The PoolState for this particular pool type is owned by the - * SharedStateHandle, so there is no object state in this class. - */ template - class AllocPool + class Pool { public: template diff --git a/src/mem/pooled.h b/src/mem/pooled.h index b685357..93daad9 100644 --- a/src/mem/pooled.h +++ b/src/mem/pooled.h @@ -8,10 +8,8 @@ namespace snmalloc class Pooled { private: - template - friend class Pool; template - friend class AllocPool; + friend class Pool; template friend class MPMCStack;