105 lines
2.8 KiB
C++
105 lines
2.8 KiB
C++
|
|
//内存设计有问题,溜了溜了。还是先学习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
|