Skip to content

Commit 36a6296

Browse files
committed
add a pm_arena_reset API method
1 parent fb8f6fa commit 36a6296

2 files changed

Lines changed: 43 additions & 6 deletions

File tree

include/prism/util/pm_arena.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,19 @@ void * pm_arena_zalloc(pm_arena_t *arena, size_t size, size_t alignment);
7878
*/
7979
void * pm_arena_memdup(pm_arena_t *arena, const void *src, size_t size, size_t alignment);
8080

81+
/**
82+
* Resets the arena. If no memory has been allocated from this arena, this
83+
* call is a no-op.
84+
*
85+
* Otherwise, a single block is retained and other blocks are freed.
86+
*
87+
* After this call, all pointers returned by pm_arena_alloc and
88+
* pm_arena_zalloc are invalid.
89+
*
90+
* @param arena The arena to reset.
91+
*/
92+
void pm_arena_reset(pm_arena_t *arena);
93+
8194
/**
8295
* Free all blocks in the arena. After this call, all pointers returned by
8396
* pm_arena_alloc and pm_arena_zalloc are invalid.

src/util/pm_arena.c

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,18 +88,42 @@ pm_arena_memdup(pm_arena_t *arena, const void *src, size_t size, size_t alignmen
8888
return dst;
8989
}
9090

91-
/**
92-
* Free all blocks in the arena.
93-
*/
9491
void
95-
pm_arena_free(pm_arena_t *arena) {
96-
pm_arena_block_t *block = arena->current;
97-
92+
free_blocks(pm_arena_block_t *block) {
9893
while (block != NULL) {
9994
pm_arena_block_t *prev = block->prev;
10095
xfree_sized(block, PM_ARENA_BLOCK_SIZE(block->capacity));
10196
block = prev;
10297
}
98+
}
99+
100+
/**
101+
* Free all but one block in the arena and mark the block as freshly allocated.
102+
*
103+
* Does nothing if the arena has never been used.
104+
*/
105+
void
106+
pm_arena_reset(pm_arent_t *arena) {
107+
pm_arena_block_t *block = arena->current;
108+
109+
if (block == NULL) {
110+
return;
111+
}
112+
113+
free_blocks(block->prev);
114+
115+
block->prev = NULL;
116+
block->used = 0;
117+
118+
arena->block_count = 1;
119+
}
120+
121+
/**
122+
* Free all blocks in the arena.
123+
*/
124+
void
125+
pm_arena_free(pm_arena_t *arena) {
126+
free_blocks(arena->current);
103127

104128
*arena = (pm_arena_t) { 0 };
105129
}

0 commit comments

Comments
 (0)