82 lines
2.0 KiB
C
82 lines
2.0 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#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);
|
|
}
|
|
}
|