zengine/engine/3rdparty/memalloc/src/memalloc.cpp

105 lines
2.8 KiB
C++
Raw Normal View History

2024-11-16 17:54:37 +08:00
//内存设计有问题溜了溜了。还是先学习mimalloc吧
#include "memory_pool_debug.h"
namespace pmr {
inline MemoryPoolManager* pMainPool;
inline BlockAllocator* pMetaAlloc;
void CleanMainMemPool() {
if (!pMainPool) return;
dumpMemoryPoolLeaks(pMainPool);
pMainPool->~MemoryPoolManager();
dumpMetaMemoryLeaks(pMetaAlloc);
pMetaAlloc->~BlockAllocator();
}
void* meta_malloc(size_t bytes, size_t alignment)
{
if (bytes > META_BLOCK_EMEM_SIZE * MAX_BLOCK_ELEM_GROUP_N || !pMetaAlloc->try_allocate(bytes)) {
return pMainPool->do_allocate(bytes, alignment);
}
using MemBlock = BlockAllocator::MemBlock;
bytes += sizeof(MemBlock);
MemBlock* pBlock = (MemBlock*)pMetaAlloc->do_allocate(bytes, alignment);
new(pBlock)MemBlock(bytes);
return (char*)pBlock + sizeof(MemBlock);
}
void meta_free(void* ptr)
{
if (!ptr) {
return;
}
using MemBlock = BlockAllocator::MemBlock;
MemBlock* pBlock = (MemBlock*)((char*)ptr - sizeof(MemBlock));
if (!*pBlock) {
pMainPool->do_deallocate(ptr);
return;
}
pMetaAlloc->do_deallocate(ptr, pBlock->size, 0);
}
}
namespace pmr {
struct MemPoolWrap {
inline static char AllocData[sizeof(BlockAllocator)];
char pMemory[sizeof(MemoryPoolManager)];
bool isMainTread;
MemPoolWrap() {
isMainTread = !pMainPool;
if (isMainTread) {
pMainPool = (MemoryPoolManager*)&pMemory;
pMetaAlloc = (BlockAllocator*)&AllocData;
std::construct_at(pMetaAlloc, MEMORY_BLOCK_SIZE, META_BLOCK_EMEM_SIZE);
std::atexit(CleanMainMemPool);
}
std::construct_at((MemoryPoolManager*)&pMemory);
}
~MemPoolWrap() {
auto pool = (MemoryPoolManager*)&pMemory;
if (!isMainTread) {//主线程最后析构
pool->~MemoryPoolManager();
}
}
MemoryPoolManager* operator->() {
return (MemoryPoolManager*)&pMemory;
}
};
}
thread_local pmr::MemPoolWrap MemPool;
MEMALLOC_API void* me_malloc(size_t size)
{
return MemPool->do_allocate(size, MEMORY_ALIGN_N);
}
MEMALLOC_API void* me_malloc_nothrow(size_t size) noexcept
{
return MemPool->do_allocate(size, MEMORY_ALIGN_N);
}
MEMALLOC_API void me_free(void* p) noexcept
{
MemPool->do_deallocate(p);
}
#if (__cplusplus >= 201402L || _MSC_VER >= 1916)
MEMALLOC_API void me_free_size(void* p, size_t size) noexcept
{
MemPool->do_deallocate(p);
}
#endif
#if (__cplusplus > 201402L || defined(__cpp_aligned_new))
MEMALLOC_API void* me_malloc_aligned(size_t size, size_t alignment)
{
return MemPool->do_allocate(size, alignment);
}
MEMALLOC_API void* me_malloc_aligned_nothrow(size_t size, size_t alignment) noexcept
{
return MemPool->do_allocate(size, alignment);
}
MEMALLOC_API void me_free_aligned(void* p, size_t alignment) noexcept
{
return MemPool->do_deallocate(p);
}
MEMALLOC_API void me_free_size_aligned(void* p, size_t size, size_t alignment) noexcept
{
MemPool->do_deallocate(p);
}
#endif