zengine/engine/3rdparty/memalloc/src/memalloc.cpp
2024-11-16 17:54:37 +08:00

105 lines
2.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//内存设计有问题溜了溜了。还是先学习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