diff --git a/src/mem/corealloc.h b/src/mem/corealloc.h index 467fa81..30dba53 100644 --- a/src/mem/corealloc.h +++ b/src/mem/corealloc.h @@ -785,4 +785,10 @@ namespace snmalloc return debug_is_empty_impl(result); } }; + + template + using AllocPool = Pool< + CoreAllocator, + SharedStateHandle, + SharedStateHandle::pool>; } // namespace snmalloc diff --git a/src/mem/globalalloc.h b/src/mem/globalalloc.h index 6f5aaad..674b7ae 100644 --- a/src/mem/globalalloc.h +++ b/src/mem/globalalloc.h @@ -11,8 +11,7 @@ namespace snmalloc static_assert( SharedStateHandle::Options.CoreAllocIsPoolAllocated, "Global statistics are available only for pool-allocated configurations"); - auto* alloc = - Pool, SharedStateHandle>::iterate(); + auto* alloc = AllocPool::iterate(); while (alloc != nullptr) { @@ -20,9 +19,7 @@ namespace snmalloc if (a != nullptr) stats.add(*a); stats.add(alloc->stats()); - alloc = - Pool, SharedStateHandle>::iterate( - alloc); + alloc = AllocPool::iterate(alloc); } } @@ -33,17 +30,14 @@ namespace snmalloc static_assert( SharedStateHandle::Options.CoreAllocIsPoolAllocated, "Global statistics are available only for pool-allocated configurations"); - auto alloc = - Pool, SharedStateHandle>::iterate(); + auto alloc = AllocPool::iterate(); while (alloc != nullptr) { auto stats = alloc->stats(); if (stats != nullptr) stats->template print(o, dumpid, alloc->id()); - alloc = - Pool, SharedStateHandle>::iterate( - alloc); + alloc = AllocPool::iterate(alloc); } } #else @@ -66,8 +60,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 = - Pool, SharedStateHandle>::extract(); + auto* first = AllocPool::extract(); auto* alloc = first; decltype(alloc) last; @@ -77,13 +70,10 @@ namespace snmalloc { alloc->flush(); last = alloc; - alloc = - Pool, SharedStateHandle>::extract( - alloc); + alloc = AllocPool::extract(alloc); } - Pool, SharedStateHandle>::restore( - first, last); + AllocPool::restore(first, last); } #endif } @@ -102,8 +92,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 = - Pool, SharedStateHandle>::iterate(); + auto* alloc = AllocPool::iterate(); # ifdef SNMALLOC_TRACING std::cout << "debug check empty: first " << alloc << std::endl; @@ -117,8 +106,7 @@ namespace snmalloc std::cout << "debug_check_empty: Check all allocators!" << std::endl; # endif done = true; - alloc = - Pool, SharedStateHandle>::iterate(); + alloc = AllocPool::iterate(); okay = true; while (alloc != nullptr) @@ -140,9 +128,7 @@ namespace snmalloc # ifdef SNMALLOC_TRACING std::cout << "debug check empty: okay = " << okay << std::endl; # endif - alloc = - Pool, SharedStateHandle>::iterate( - alloc); + alloc = AllocPool::iterate(alloc); } } @@ -155,14 +141,11 @@ namespace snmalloc // Redo check so abort is on allocator with allocation left. if (!okay) { - alloc = - Pool, SharedStateHandle>::iterate(); + alloc = AllocPool::iterate(); while (alloc != nullptr) { alloc->debug_is_empty(nullptr); - alloc = - Pool, SharedStateHandle>::iterate( - alloc); + alloc = AllocPool::iterate(alloc); } } #else @@ -176,8 +159,7 @@ namespace snmalloc static_assert( SharedStateHandle::Options.CoreAllocIsPoolAllocated, "Global status is available only for pool-allocated configurations"); - auto alloc = - Pool, SharedStateHandle>::iterate(); + auto alloc = AllocPool::iterate(); while (alloc != nullptr) { if (alloc->debug_is_in_use()) @@ -188,9 +170,7 @@ namespace snmalloc } count--; } - alloc = - Pool, SharedStateHandle>::iterate( - alloc); + alloc = AllocPool::iterate(alloc); if (count != 0) { diff --git a/src/mem/localalloc.h b/src/mem/localalloc.h index 96c1e56..03161fa 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(Pool::acquire(&(this->local_cache))); + init(AllocPool::acquire(&(this->local_cache))); } // Return all state in the fast allocator and release the underlying @@ -402,7 +402,7 @@ namespace snmalloc // Return underlying allocator to the system. if constexpr (SharedStateHandle::Options.CoreAllocOwnsLocalState) { - Pool::release(core_alloc); + AllocPool::release(core_alloc); } // Set up thread local allocator to look like diff --git a/src/mem/pool.h b/src/mem/pool.h index 184abca..76950c2 100644 --- a/src/mem/pool.h +++ b/src/mem/pool.h @@ -21,7 +21,10 @@ namespace snmalloc template class PoolState { - template + template< + typename TT, + typename SharedStateHandle, + PoolState& get_state()> friend class Pool; private: @@ -34,35 +37,28 @@ namespace snmalloc }; /** - * Class used to instantiate non-allocator pools using a Singleton PoolState. + * Class used to instantiate a global non-allocator PoolState. */ - template - class PoolStateHandle + template + class SingletonPoolState { - static PoolState& pool_state = - Singleton, PoolStateHandle::make_state>::get(); - - static PoolState* make_state() - { - return ChunkAllocator::alloc_meta_data, SharedStateHandle>( - nullptr); - } + static inline PoolState state; public: static PoolState& pool() { - return pool_state; + return state; } }; - template + template& get_state()> class Pool { public: template static T* acquire(Args&&... args) { - PoolState& pool = SharedStateHandle::pool(); + PoolState& pool = get_state(); T* p = pool.stack.pop(); if (p != nullptr) @@ -99,14 +95,14 @@ namespace snmalloc // is returned without the constructor being run, so the object is reused // without re-initialisation. p->reset_in_use(); - SharedStateHandle::pool().stack.push(p); + get_state().stack.push(p); } static T* extract(T* p = nullptr) { // Returns a linked list of all objects in the stack, emptying the stack. if (p == nullptr) - return SharedStateHandle::pool().stack.pop_all(); + return get_state().stack.pop_all(); return p->next; } @@ -120,13 +116,13 @@ namespace snmalloc { // Pushes a linked list of objects onto the stack. Use to put a linked // list returned by extract back onto the stack. - SharedStateHandle::pool().stack.push(first, last); + get_state().stack.push(first, last); } static T* iterate(T* p = nullptr) { if (p == nullptr) - return SharedStateHandle::pool().list; + return get_state().list; return p->list_next; } diff --git a/src/mem/pooled.h b/src/mem/pooled.h index 657ea2d..d5b988c 100644 --- a/src/mem/pooled.h +++ b/src/mem/pooled.h @@ -4,11 +4,17 @@ namespace snmalloc { + template + class PoolState; + template class Pooled { - private: - template + public: + template< + typename TT, + typename SharedStateHandle, + PoolState& get_state()> friend class Pool; template friend class MPMCStack;