Create mimalloc heaps only when necessary.

The mimalloc temporary heap is a thread-local object that uses RAII
to manage heap lifetimes even in threads that are created implicitly,
e.g. by OpenMP. However, not all threads are necessarily created by
the application; graphics drivers may create their own threads, and
this can lead to deadlocks when combined with library unloading.

Fixes #657.
This commit is contained in:
whitequark 2020-07-22 11:04:48 +00:00
parent 188b2e26ce
commit b0fc1912ea

View File

@ -684,13 +684,10 @@ void DebugPrint(const char *fmt, ...) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
struct MimallocHeap { struct MimallocHeap {
mi_heap_t *heap = mi_heap_new(); mi_heap_t *heap = NULL;
MimallocHeap() {
ssassert(heap != NULL, "out of memory");
}
~MimallocHeap() { ~MimallocHeap() {
if(heap != NULL)
mi_heap_destroy(heap); mi_heap_destroy(heap);
} }
}; };
@ -698,6 +695,10 @@ struct MimallocHeap {
static thread_local MimallocHeap TempArena; static thread_local MimallocHeap TempArena;
void *AllocTemporary(size_t size) { void *AllocTemporary(size_t size) {
if(TempArena.heap == NULL) {
TempArena.heap = mi_heap_new();
ssassert(TempArena.heap != NULL, "out of memory");
}
void *ptr = mi_heap_zalloc(TempArena.heap, size); void *ptr = mi_heap_zalloc(TempArena.heap, size);
ssassert(ptr != NULL, "out of memory"); ssassert(ptr != NULL, "out of memory");
return ptr; return ptr;