#pragma once #include "../backend/backend.h" #include "../mem/corealloc.h" #include "../mem/pool.h" #include "../mem/slaballocator.h" #include "commonconfig.h" #include namespace snmalloc { // Forward reference to thread local cleanup. void register_clean_up(); #ifdef USE_SNMALLOC_STATS inline static void print_stats() { printf("No Stats yet!"); // Stats s; // current_alloc_pool()->aggregate_stats(s); // s.print(std::cout); } #endif /** * The default configuration for a global snmalloc. This allocates memory * from the operating system and expects to manage memory anywhere in the * address space. */ class Globals final : public BackendAllocator { private: using Backend = BackendAllocator; SNMALLOC_REQUIRE_CONSTINIT inline static ChunkAllocatorState slab_allocator_state; SNMALLOC_REQUIRE_CONSTINIT inline static PoolState> alloc_pool; SNMALLOC_REQUIRE_CONSTINIT inline static std::atomic initialised{false}; SNMALLOC_REQUIRE_CONSTINIT inline static std::atomic_flag initialisation_lock{}; public: static ChunkAllocatorState& get_slab_allocator_state(Backend::LocalState* = nullptr) { return slab_allocator_state; } static PoolState>& pool() { return alloc_pool; } static constexpr Flags Options{}; // Performs initialisation for this configuration // of allocators. Needs to be idempotent, // and concurrency safe. static void ensure_init() { FlagLock lock{initialisation_lock}; #ifdef SNMALLOC_TRACING std::cout << "Run init_impl" << std::endl; #endif if (initialised) return; LocalEntropy entropy; entropy.init(); // Initialise key for remote deallocation lists key_global = FreeListKey(entropy.get_free_list_key()); // Need to initialise pagemap. Backend::init(); #ifdef USE_SNMALLOC_STATS atexit(snmalloc::print_stats); #endif initialised = true; } static bool is_initialised() { return initialised; } // This needs to be a forward reference as the // thread local state will need to know about this. // This may allocate, so should only be called once // a thread local allocator is available. static void register_clean_up() { snmalloc::register_clean_up(); } }; } // namespace snmalloc