#include #include #include "slab.h" //------------------------------------------------------------------------------ Allocator::~Allocator() { if (_slab != nullptr) _slab->dec_ref(); } //------------------------------------------------------------------------------ MutableBuffer Allocator::create_buffer(uint32 size) { auto create_slab = [this] (uint32 slab_size) { auto* slab = tt_malloc(slab_size + sizeof(Slab)); slab->_allocator = this; slab->_size = slab_size; slab->_refs.store_relaxed(0); return slab; }; enum { PACKET_PAGE_SIZE = 4 << 10, PACKET_SLAB_SIZE = 1 << 20, PACKET_ALIGN = 32 - 1, }; if (size > PACKET_PAGE_SIZE) { Slab* slab = create_slab(size); return MutableBuffer(slab, size, 0); } uint32 alloc_size = (size + PACKET_ALIGN) & ~PACKET_ALIGN; UniqueLock _(_lock); if (alloc_size > _slab_free && _slab != nullptr) { _slab->dec_ref(); _slab = nullptr; } if (_slab == nullptr) { _slab_free = PACKET_SLAB_SIZE; _slab = create_slab(_slab_free); _slab->inc_ref(); } uint32 offset = PACKET_SLAB_SIZE - _slab_free; _slab_free -= alloc_size; return MutableBuffer(_slab, size, offset); } //------------------------------------------------------------------------------ void Allocator::free_slab(Slab* slab) { tt_free(slab); } //------------------------------------------------------------------------------ Allocator& Allocator::get_from(Buffer& buffer) { return get_from(buffer._slab); } Allocator& Allocator::get_from(BufferRef& ref) { return get_from(ref.get_slab()); } Allocator& Allocator::get_from(BufferStream& stream){ return get_from(stream.get_slab()); } Allocator& Allocator::get_from(Pointer& pointer) { return get_from(pointer.get_slab()); } Allocator& Allocator::get_from(const Slab* slab) { return slab->get_allocator(); }