Skip to content

Commit

Permalink
Replace {Alloc,FreeAll}Temporary() with mimalloc
Browse files Browse the repository at this point in the history
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
  • Loading branch information
nabijaczleweli committed Jul 9, 2020
1 parent faa05c0 commit 3c085a9
Showing 1 changed file with 18 additions and 49 deletions.
67 changes: 18 additions & 49 deletions src/platform/platform.cpp
Expand Up @@ -10,6 +10,7 @@
# include <CoreFoundation/CFBundle.h>
#endif
#include "solvespace.h"
#include "mimalloc.h"
#include "config.h"
#if defined(WIN32)
// Conversely, include Microsoft headers after solvespace.h to avoid clashes.
Expand All @@ -18,7 +19,6 @@
#else
# include <unistd.h>
# include <sys/stat.h>
# include <mutex>
#endif

namespace SolveSpace {
Expand Down Expand Up @@ -680,64 +680,33 @@ void DebugPrint(const char *fmt, ...) {
#endif

//-----------------------------------------------------------------------------
// Temporary arena, on Windows.
// Temporary arena.
//-----------------------------------------------------------------------------

#if defined(WIN32)

static HANDLE TempArena = NULL;

void *AllocTemporary(size_t size)
{
if(!TempArena)
TempArena = HeapCreate(0, 0, 0);
void *ptr = HeapAlloc(TempArena, HEAP_ZERO_MEMORY, size);
ssassert(ptr != NULL, "out of memory");
return ptr;
}
struct MimallocHeap {
mi_heap_t *heap = mi_heap_new();

void FreeAllTemporary()
{
HeapDestroy(TempArena);
TempArena = NULL;
}

#endif

//-----------------------------------------------------------------------------
// Temporary arena, on Linux.
//-----------------------------------------------------------------------------

#if !defined(WIN32)
MimallocHeap() {
ssassert(heap != NULL, "out of memory");
}

struct ArenaChunk {
ArenaChunk *next;
~MimallocHeap() {
mi_heap_destroy(heap);
}
};

static std::mutex TempArenaMutex;
static ArenaChunk *TempArena = NULL;
static thread_local MimallocHeap TempArena;

void *AllocTemporary(size_t size)
{
ArenaChunk *chunk = (ArenaChunk *)calloc(1, sizeof(ArenaChunk) + size);
ssassert(chunk != NULL, "out of memory");
std::lock_guard<std::mutex> guard(TempArenaMutex);
chunk->next = TempArena;
TempArena = chunk;
return (void *)(chunk + 1);
void *AllocTemporary(size_t size) {
void *ptr = mi_heap_zalloc(TempArena.heap, size);
ssassert(ptr != NULL, "out of memory");
return ptr;
}

void FreeAllTemporary()
{
std::lock_guard<std::mutex> guard(TempArenaMutex);
while(TempArena) {
ArenaChunk *chunk = TempArena;
TempArena = TempArena->next;
free(chunk);
}
void FreeAllTemporary() {
MimallocHeap temp;
std::swap(TempArena.heap, temp.heap);
}

#endif

}
}

0 comments on commit 3c085a9

Please sign in to comment.