Files
snmalloc/src/backend/globalconfig.h
2021-10-20 18:38:08 +01:00

108 lines
2.5 KiB
C++

#pragma once
#include "../backend/backend.h"
#include "../mem/chunkallocator.h"
#include "../mem/corealloc.h"
#include "../mem/pool.h"
#include "commonconfig.h"
#ifdef SNMALLOC_TRACING
# include <iostream>
#endif
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<Alloc>(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<Pal, false>
{
public:
using GlobalPoolState = PoolState<CoreAllocator<Globals>>;
private:
using Backend = BackendAllocator<Pal, false>;
SNMALLOC_REQUIRE_CONSTINIT
inline static ChunkAllocatorState chunk_allocator_state;
SNMALLOC_REQUIRE_CONSTINIT
inline static GlobalPoolState alloc_pool;
SNMALLOC_REQUIRE_CONSTINIT
inline static std::atomic<bool> initialised{false};
SNMALLOC_REQUIRE_CONSTINIT
inline static std::atomic_flag initialisation_lock{};
public:
static ChunkAllocatorState&
get_chunk_allocator_state(Backend::LocalState* = nullptr)
{
return chunk_allocator_state;
}
static GlobalPoolState& 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<Pal>();
// 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