NAME
arena_alloc,
arena_free, arena_scope,
arena_malloc, arena_calloc,
arena_realloc,
arena_sprintf, arena_strdup,
arena_strndup,
arena_cleanup, arena_stats,
arena_poison —
scoped based allocator
SYNOPSIS
#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);
DESCRIPTION
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
arena_scope().
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
arena_alloc()
function allocates a new arena. The name is only
consumed by arena-trace(1) and can be omitted as in passing
NULL.
The
arena_free()
function frees the arena and invalidates any associated scope still
alive.
The
arena_scope()
function initializes a new scope.
The
arena_malloc()
function behaves like
malloc(3).
The
arena_calloc()
function behaves like
calloc(3).
The
arena_realloc()
reallocates ptr to new_size.
Passing an object which is not allocated from the arena is considered
undefined behavior.
The
arena_sprintf()
function behaves like
sprintf(3) with the exception of the buffer being allocated
from the arena.
The
arena_strdup()
function behaves like
strdup(3).
The
arena_strndup()
function behaves like
strndup(3).
The
arena_cleanup()
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
arena_stats()
function return statistics for the arena.
The
arena_poison()
poisons the memory range [ptr, ptr + size). Intended to be used before the
associated arena scope goes out of lexical scope. See
SANITIZERS.
RETURN VALUES
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.
SANITIZERS
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.
EXAMPLES
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;
}
SEE ALSO
AUTHORS
Anton Lindqvist <anton@basename.se>