zengine/engine/modules/engine/zlib/include/pmr/frame_allocator.inl
2024-10-23 15:24:39 +08:00

65 lines
1.7 KiB
C++

namespace pmr {
inline void* try_allocate(FrameAllocator& allac, size_t bytes, size_t alignment)
{
if (allac.capacity - allac.offset > bytes) {
return allac.do_allocate(bytes, alignment);
}
return nullptr;
}
inline void* FrameAllocator::do_allocate(size_t bytes, size_t alignment)
{
size_t space = capacity - offset;
void* ptr = buffer + offset;
if (std::align(alignment, bytes, ptr, space)) {
offset = capacity - space + bytes;
return ptr;
}
throw std::bad_alloc();
}
inline void* FrameAllocatorPool::allocate(size_t bytes, size_t alignment)
{
for (auto& alllocator : allocators) {
if (auto ptr = try_allocate(alllocator, bytes, alignment)) {
return ptr;
}
}
// 如果所有现有的分配器都没有足够的空间,则创建一个新的分配器
auto& it = allocators.emplace_back(allocatorSize);
return it.allocate(bytes, alignment);
}
inline void FrameAllocatorPool::reset()
{
size_t count = 0;
for (auto& allocator : allocators) {
if (!allocator.empty()) {
allocator.reset();
count++;
}
}
count = count > 0 ? count : 1;
allocators.erase(allocators.begin() + count, allocators.end());
}
#ifdef ZLIB_API_VAL //内存分配和释放必须位于同一模块(DLL)
inline FrameAllocator& FrameAllocator::operator=(FrameAllocator&& o)noexcept
{
std::construct_at(this, std::forward<FrameAllocator&&>(o));
return *this;
}
inline FrameAllocator::FrameAllocator(FrameAllocator&& o) noexcept :buffer(o.buffer), capacity(o.capacity), offset(o.offset)
{
o.move_clear();
}
inline FrameAllocator::FrameAllocator(size_t size)noexcept
{
buffer = new char[size];
capacity = size;
offset = 0;
}
inline FrameAllocator::~FrameAllocator()noexcept
{
if (buffer)
delete[] buffer;
}
#endif
};