From c4ca4be91e0f38646fa391aaca6fd58e505be4c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= Date: Thu, 9 Jul 2020 15:27:35 +0200 Subject: [PATCH] Replace {Alloc,FreeAll}Temporary() with mimalloc The heaps are wrapped in a RAIIish thread_local handler, since being affined affined to a single thread for allocations is required by the API Ref: #642 --- src/platform/platform.cpp | 69 +++++++++++---------------------------- 1 file changed, 19 insertions(+), 50 deletions(-) diff --git a/src/platform/platform.cpp b/src/platform/platform.cpp index a1d29ea8..934220ca 100644 --- a/src/platform/platform.cpp +++ b/src/platform/platform.cpp @@ -10,6 +10,7 @@ # include #endif #include "solvespace.h" +#include "mimalloc.h" #include "config.h" #if defined(WIN32) // Conversely, include Microsoft headers after solvespace.h to avoid clashes. @@ -18,7 +19,6 @@ #else # include # include -# include #endif namespace SolveSpace { @@ -680,64 +680,33 @@ void DebugPrint(const char *fmt, ...) { #endif //----------------------------------------------------------------------------- -// Temporary arena, on Windows. +// Temporary arena. //----------------------------------------------------------------------------- -#if defined(WIN32) +struct MimallocHeap { + mi_heap_t *heap = mi_heap_new(); -static HANDLE TempArena = NULL; + MimallocHeap() { + ssassert(heap != NULL, "out of memory"); + } -void *AllocTemporary(size_t size) -{ - if(!TempArena) - TempArena = HeapCreate(0, 0, 0); - void *ptr = HeapAlloc(TempArena, HEAP_ZERO_MEMORY, size); + ~MimallocHeap() { + mi_heap_destroy(heap); + } +}; + +static thread_local MimallocHeap TempArena; + +void *AllocTemporary(size_t size) { + void *ptr = mi_heap_zalloc(TempArena.heap, size); ssassert(ptr != NULL, "out of memory"); return ptr; } -void FreeAllTemporary() -{ - HeapDestroy(TempArena); - TempArena = NULL; +void FreeAllTemporary() { + MimallocHeap temp; + std::swap(TempArena.heap, temp.heap); } -#endif - -//----------------------------------------------------------------------------- -// Temporary arena, on Linux. -//----------------------------------------------------------------------------- - -#if !defined(WIN32) - -struct ArenaChunk { - ArenaChunk *next; -}; - -static std::mutex TempArenaMutex; -static ArenaChunk *TempArena = NULL; - -void *AllocTemporary(size_t size) -{ - ArenaChunk *chunk = (ArenaChunk *)calloc(1, sizeof(ArenaChunk) + size); - ssassert(chunk != NULL, "out of memory"); - std::lock_guard guard(TempArenaMutex); - chunk->next = TempArena; - TempArena = chunk; - return (void *)(chunk + 1); -} - -void FreeAllTemporary() -{ - std::lock_guard guard(TempArenaMutex); - while(TempArena) { - ArenaChunk *chunk = TempArena; - TempArena = TempArena->next; - free(chunk); - } -} - -#endif - } }