ARENA(3) Library Functions Manual ARENA(3)

arena_alloc, arena_free, arena_scope, arena_malloc, arena_calloc, arena_realloc, arena_sprintf, arena_strdup, arena_strndup, arena_cleanup, arena_stats, arena_poisonscoped based allocator

#include <libks/arena.h>

struct arena *
arena_alloc(const char *name);

void
arena_free(struct arena *arena);

void
arena_scope(struct arena *arena, varname);

void *
arena_malloc(struct arena_scope *scope, size_t size);

void *
arena_calloc(struct arena_scope *scope, size_t nmemb, size_t size);

void *
arena_realloc(struct arena_scope *scope, void *ptr, size_t old_size, size_t new_size);

char *
arena_sprintf(struct arena_scope *scope, const char *fmt, ...);

char *
arena_strdup(struct arena_scope *scope, const char *str);

char *
arena_strndup(struct arena_scope *scope, const char *str, size_t len);

void
arena_cleanup(struct arena_scope *scope, void (*callback)(void *), void *ptr);

struct arena_stats *
arena_stats(struct arena *arena);

void
arena_poison(const void *ptr, size_t len);

The arena is a scoped based allocator which removes the need to explicitly free allocated objects.

In order to perform arena allocations, a scope must be entered by initializing a variable using (). All allocations associated with the arena scope will be freed once the variable goes out of lexical scope. If a lexical scope, often a function, must perform allocations that outlives its own scope, it is advised use an arena scope declared in an outer lexical scope.

The () function allocates a new arena. The name is only consumed by arena-trace(1) and can be omitted as in passing NULL.

The () function frees the arena and invalidates any associated scope still alive.

The () function initializes a new scope.

The () function behaves like malloc(3).

The () function behaves like calloc(3).

The () reallocates ptr to new_size. Passing an object which is not allocated from the arena is considered undefined behavior.

The () function behaves like sprintf(3) with the exception of the buffer being allocated from the arena.

The () function behaves like strdup(3).

The () function behaves like strndup(3).

The () function registers callback to be called with ptr given as the first and only argument once the given scope goes out of lexical scope. If multiple callbacks are registered, they will be executed in reverse order of registration. Intended to be used with objects requiring additional handling during destruction such as freeing allocations from elsewhere.

The () function return statistics for the arena.

The () poisons the memory range [ptr, ptr + size). Intended to be used before the associated arena scope goes out of lexical scope. See SANITIZERS.

The arena_alloc() function returns a pointer to the allocated arena on success. Otherwise, the process is terminated.

The arena_malloc(), arena_calloc(), arena_realloc(), arena_sprintf(), arena_strdup() and arena_strndup() functions returns a pointer to the allocated object on success. Otherwise, the process is terminated.

The arena is compatible with the AddressSanitizer (ASAN) and Valgrind. All allocated objects associated with an arena scope will be poisoned once they goes out of scope.

The following example shows how to perform arena allocations that outlives its own lexical scope.

char *
numtostr(int num, struct arena_scope *s)
{
	return arena_sprintf(s, "%d", num);
}

int
main(void)
{
	struct arena *arena;
	char *str;

	arena = arena_alloc(NULL);

	arena_scope(arena, s);

	{
		arena_scope(arena, scratch);
		str = arena_strdup(scratch, "ephemeral");
	}
	/* str no longer accessible */

	str = numtostr(42, &s);
	/* str still accessible */

	arena_free(arena);
	return 0;
}

The following example shows how arena_cleanup() can be used to free objects allocated from elsewhere. Once the arena scope goes out of lexical scope, regex_free() will be called.

#include <regex.h>

void
regex_free(void *arg)
{
	regex_t *re = arg;

	regfree(re);
}

regex_t *
regex_compile(const char *pattern, struct arena_scope *s)
{
	regex_t *re;

	re = arena_malloc(s, sizeof(*re));
	if (regcomp(re, pattern, 0))
		/* Omitted error handling. */;
	arena_cleanup(s, regex_free, re);
	return re;
}

arena-trace(1), arena_buffer(3), arena_vector(3)

Anton Lindqvist <anton@basename.se>

OpenBSD 7.8 September 27, 2023 ARENA(3)