test/refactor: lock approach taken, best one
This commit is contained in:
@@ -17,6 +17,7 @@ typedef enum {
|
|||||||
ARENA_INVALID_SIZE,
|
ARENA_INVALID_SIZE,
|
||||||
ARENA_INVALID_ALIGN,
|
ARENA_INVALID_ALIGN,
|
||||||
ARENA_CAPACITY_OVERFLOW,
|
ARENA_CAPACITY_OVERFLOW,
|
||||||
|
ARENA_LOCKED,
|
||||||
} ArenaErr;
|
} ArenaErr;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -37,7 +38,7 @@ typedef struct {
|
|||||||
ArenaErr err;
|
ArenaErr err;
|
||||||
Allocator allocator;
|
Allocator allocator;
|
||||||
};
|
};
|
||||||
} ArenaAllocResult;
|
} ArenaAllocator;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool is_valid;
|
bool is_valid;
|
||||||
@@ -63,6 +64,9 @@ ArenaSizeResult arena_get_align_padding(Arena *arena, size_t alignment);
|
|||||||
// I shouldn't cover.
|
// I shouldn't cover.
|
||||||
ArenaErr arena_ensure_capacity(Arena *arena, size_t size, size_t alignment);
|
ArenaErr arena_ensure_capacity(Arena *arena, size_t size, size_t alignment);
|
||||||
|
|
||||||
ArenaAllocResult arena_get_allocator(Arena *arena);
|
ArenaErr arena_lock_growth(Arena *arena);
|
||||||
|
ArenaErr arena_unlock_growth(Arena *arena);
|
||||||
|
|
||||||
|
ArenaAllocator arena_get_allocator(Arena *arena);
|
||||||
|
|
||||||
#endif // !RENA_H
|
#endif // !RENA_H
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ struct Arena {
|
|||||||
size_t capacity;
|
size_t capacity;
|
||||||
size_t offset;
|
size_t offset;
|
||||||
|
|
||||||
|
bool growth_locked;
|
||||||
Allocator allocator;
|
Allocator allocator;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -50,6 +51,7 @@ ArenaErr arena_init(Arena **arena, Allocator allocator, size_t capacity) {
|
|||||||
.buffer = buffer,
|
.buffer = buffer,
|
||||||
.capacity = capacity,
|
.capacity = capacity,
|
||||||
.offset = 0,
|
.offset = 0,
|
||||||
|
.growth_locked = false,
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -68,6 +70,7 @@ ArenaErr arena_destroy(Arena **arena) {
|
|||||||
tmp->buffer = NULL;
|
tmp->buffer = NULL;
|
||||||
tmp->offset = 0;
|
tmp->offset = 0;
|
||||||
tmp->capacity = 0;
|
tmp->capacity = 0;
|
||||||
|
tmp->growth_locked = false;
|
||||||
tmp->allocator
|
tmp->allocator
|
||||||
.free(tmp->allocator.ctx, *arena, sizeof(Arena), alignof(Arena));
|
.free(tmp->allocator.ctx, *arena, sizeof(Arena), alignof(Arena));
|
||||||
*arena = NULL;
|
*arena = NULL;
|
||||||
@@ -209,6 +212,10 @@ ArenaErr arena_resize(Arena *arena, size_t new_capacity) {
|
|||||||
return ARENA_INVALID_SIZE;
|
return ARENA_INVALID_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (arena->growth_locked) {
|
||||||
|
return ARENA_LOCKED;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t *tmp = arena->allocator.realloc(
|
uint8_t *tmp = arena->allocator.realloc(
|
||||||
arena->allocator.ctx,
|
arena->allocator.ctx,
|
||||||
arena->buffer,
|
arena->buffer,
|
||||||
@@ -241,6 +248,24 @@ ArenaSizeResult arena_get_align_padding(Arena *arena, size_t alignment) {
|
|||||||
return (ArenaSizeResult){.is_valid = true, .val = padding};
|
return (ArenaSizeResult){.is_valid = true, .val = padding};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ArenaErr arena_lock_growth(Arena *arena) {
|
||||||
|
if (arena == NULL) {
|
||||||
|
return ARENA_NULL_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
arena->growth_locked = true;
|
||||||
|
return ARENA_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArenaErr arena_unlock_growth(Arena *arena) {
|
||||||
|
if (arena == NULL) {
|
||||||
|
return ARENA_NULL_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
arena->growth_locked = false;
|
||||||
|
return ARENA_OK;
|
||||||
|
}
|
||||||
|
|
||||||
void *arena_unwrap_pointer(ArenaPointer p) {
|
void *arena_unwrap_pointer(ArenaPointer p) {
|
||||||
if (!p.is_valid) {
|
if (!p.is_valid) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -268,19 +293,21 @@ arena_allocator_free(void *ctx, void *pointer, size_t size, size_t alignment) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArenaAllocResult arena_get_allocator(Arena *arena) {
|
ArenaAllocator arena_get_allocator(Arena *arena) {
|
||||||
if (arena == NULL) {
|
if (arena == NULL) {
|
||||||
return (ArenaAllocResult){
|
return (ArenaAllocator){
|
||||||
.is_valid = false,
|
.is_valid = false,
|
||||||
.err = ARENA_NULL_ARG,
|
.err = ARENA_NULL_ARG,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arena->growth_locked = true;
|
||||||
|
|
||||||
Allocator allocator = {
|
Allocator allocator = {
|
||||||
.alloc = arena_allocator_alloc,
|
.alloc = arena_allocator_alloc,
|
||||||
.realloc = arena_allocator_realloc,
|
.realloc = arena_allocator_realloc,
|
||||||
.free = arena_allocator_free,
|
.free = arena_allocator_free,
|
||||||
.ctx = arena};
|
.ctx = arena};
|
||||||
|
|
||||||
return (ArenaAllocResult){.is_valid = true, .allocator = allocator};
|
return (ArenaAllocator){.is_valid = true, .allocator = allocator};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,6 +209,59 @@ static void test_arena_ensure_capacity_align_max(void **state) {
|
|||||||
arena_destroy(&arena);
|
arena_destroy(&arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_arena_allocator_valid_allocation(void **state) {
|
||||||
|
(void)state;
|
||||||
|
|
||||||
|
Arena *arena;
|
||||||
|
assert_uint_equal(arena_init(&arena, allocator_default(), 64), ARENA_OK);
|
||||||
|
|
||||||
|
ArenaAllocator result = arena_get_allocator(arena);
|
||||||
|
assert_true(result.is_valid);
|
||||||
|
|
||||||
|
Allocator arena_allocator = result.allocator;
|
||||||
|
|
||||||
|
int *x =
|
||||||
|
arena_allocator.alloc(arena_allocator.ctx, sizeof(int), alignof(int));
|
||||||
|
|
||||||
|
assert_non_null(x);
|
||||||
|
|
||||||
|
*x = 34;
|
||||||
|
assert_int_equal(*x, 34);
|
||||||
|
|
||||||
|
arena_destroy(&arena);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_arena_allocatro_many_allocations(void **state) {
|
||||||
|
(void)state;
|
||||||
|
|
||||||
|
Arena *arena;
|
||||||
|
assert_uint_equal(arena_init(&arena, allocator_default(), 64), ARENA_OK);
|
||||||
|
|
||||||
|
ArenaAllocator result = arena_get_allocator(arena);
|
||||||
|
assert_true(result.is_valid);
|
||||||
|
|
||||||
|
Allocator arena_allocator = result.allocator;
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
int *x = arena_allocator.alloc(
|
||||||
|
arena_allocator.ctx,
|
||||||
|
sizeof(int),
|
||||||
|
alignof(int));
|
||||||
|
|
||||||
|
assert_non_null(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
arena_destroy(&arena);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_arena_allocator_from_null_arena(void **state) {
|
||||||
|
(void)state;
|
||||||
|
|
||||||
|
Arena *arena = NULL;
|
||||||
|
|
||||||
|
ArenaAllocator result = arena_get_allocator(arena);
|
||||||
|
assert_false(result.is_valid);
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
const struct CMUnitTest tests[] = {
|
const struct CMUnitTest tests[] = {
|
||||||
cmocka_unit_test(test_push_3_ints),
|
cmocka_unit_test(test_push_3_ints),
|
||||||
@@ -223,6 +276,7 @@ int main(void) {
|
|||||||
cmocka_unit_test(test_arena_ensure_capacity_align_max),
|
cmocka_unit_test(test_arena_ensure_capacity_align_max),
|
||||||
cmocka_unit_test(test_arena_ensure_capacity_size_0),
|
cmocka_unit_test(test_arena_ensure_capacity_size_0),
|
||||||
cmocka_unit_test(test_arena_ensure_capacity_size_max),
|
cmocka_unit_test(test_arena_ensure_capacity_size_max),
|
||||||
|
cmocka_unit_test(test_arena_allocator_valid_allocation),
|
||||||
};
|
};
|
||||||
|
|
||||||
return cmocka_run_group_tests(tests, NULL, NULL);
|
return cmocka_run_group_tests(tests, NULL, NULL);
|
||||||
|
|||||||
Reference in New Issue
Block a user