#include #include #include "arena.h" #if __STDC_VERSION__ >= 201112L /* C11 and above */ #define thread_local _Thread_local #elif defined(__GNUC__) #define thread_local __thread #else #error Unsupported compiler. #endif #if defined(__GNUC__) #define WEAK __attribute__((weak)) #endif thread_local arena_t *arena_scratch_list[4] = { 0 }; void arena_scratch_destroy(void) { for (int s = 0; s < sizeof(arena_scratch_list) / sizeof(arena_scratch_list[0]); s++) { if (arena_scratch_list[s] == NULL) continue; arena_del(arena_scratch_list[s]); arena_scratch_list[s] = NULL; } } /* * Optionally allocate and return a scratch arena. Make sure that the returned * arena is not present in the NULL-terminated list `conflicts` */ arena_t *__arena_scratch(arena_t **conflicts) { int s = 0; if (conflicts != NULL) { for (s = 0; s < sizeof(arena_scratch_list) / sizeof(arena_scratch_list[0]); s++) { arena_t **c = conflicts; for (; *c != NULL; c++) { if (*c == arena_scratch_list[s]) break; } /* No conflcits found, break out */ if (*c == NULL) break; } if (s >= sizeof(arena_scratch_list) / sizeof(arena_scratch_list[0])) { fprintf(stderr, "Out of scratch arenas.\n"); return NULL; } } if (arena_scratch_list[s] == NULL) { arena_scratch_init(); arena_scratch_list[s] = arena_new(ARENA_SCRATCH_DEFAULT_SIZE); if (arena_scratch_list[s] == NULL) { fprintf(stderr, "Error allocating scratch arena %d.", s); return NULL; } printf("NEW SCRATCH = %p\n", arena_scratch_list[s]); } return arena_scratch_list[s]; } void WEAK arena_scratch_init(void) { static bool init = false; for (;!init; init = true) { printf("Single-threaded mode.\n"); atexit(arena_scratch_destroy); } }