Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions include/prism/util/pm_arena.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,19 @@ void * pm_arena_zalloc(pm_arena_t *arena, size_t size, size_t alignment);
*/
void * pm_arena_memdup(pm_arena_t *arena, const void *src, size_t size, size_t alignment);

/**
* Resets the arena. If no memory has been allocated from this arena, this
* call is a no-op.
*
* Otherwise, a single block is retained and other blocks are freed.
*
* After this call, all pointers returned by pm_arena_alloc and
* pm_arena_zalloc are invalid.
*
* @param arena The arena to reset.
*/
void pm_arena_reset(pm_arena_t *arena);

/**
* Free all blocks in the arena. After this call, all pointers returned by
* pm_arena_alloc and pm_arena_zalloc are invalid.
Expand Down
36 changes: 30 additions & 6 deletions src/util/pm_arena.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,42 @@ pm_arena_memdup(pm_arena_t *arena, const void *src, size_t size, size_t alignmen
return dst;
}

/**
* Free all blocks in the arena.
*/
void
pm_arena_free(pm_arena_t *arena) {
pm_arena_block_t *block = arena->current;

free_blocks(pm_arena_block_t *block) {
while (block != NULL) {
pm_arena_block_t *prev = block->prev;
xfree_sized(block, PM_ARENA_BLOCK_SIZE(block->capacity));
block = prev;
}
}

/**
* Free all but one block in the arena and mark the block as freshly allocated.
*
* Does nothing if the arena has never been used.
*/
void
pm_arena_reset(pm_arena_t *arena) {
pm_arena_block_t *block = arena->current;

if (block == NULL) {
return;
}

free_blocks(block->prev);

block->prev = NULL;
block->used = 0;

arena->block_count = 1;
}

/**
* Free all blocks in the arena.
*/
void
pm_arena_free(pm_arena_t *arena) {
free_blocks(arena->current);

*arena = (pm_arena_t) { 0 };
}