Arena initial implementation.

Signed-off-by: Mitja Horvat <mitja@plume.com>
This commit is contained in:
Mitja Horvat
2024-11-08 08:49:22 +01:00
commit ebea1803c9
5 changed files with 526 additions and 0 deletions

81
src/arena_scratch.c Normal file
View File

@ -0,0 +1,81 @@
#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);
}
}