#pragma once /// \file slab_allocated.h /// A parent template class for slab-allocated objects #include #include #include #include "memory.h" template class slab_allocated { public: static constexpr size_t slab_size = N; void * operator new(size_t size) { kassert(size == sizeof(T), "Slab allocator got wrong size allocation"); if (s_free.count() == 0) allocate_chunk(); T *item = s_free.pop(); memset(item, 0, sizeof(T)); return item; } void operator delete(void *p) { s_free.append(reinterpret_cast(p)); } private: constexpr static size_t per_block = slab_size / sizeof(T); static void allocate_chunk() { s_free.ensure_capacity(per_block); uint8_t *start = new uint8_t [slab_size]; T *current = reinterpret_cast(start); T *end = util::offset_pointer(current, slab_size); while (current < end) s_free.append(current++); } static util::vector s_free; }; template util::vector slab_allocated::s_free; #define DEFINE_SLAB_ALLOCATOR(type) \ template<> util::vector slab_allocated::s_free {};