Files
allocators/tests/arena_allocator.c
T
2026-08-07 18:33:50 -05:00

420 lines
12 KiB
C

#include <stdio.h>
#include "malunal/allocators/arena.h"
const malunal_size_t page_bytes = 4096;
const malunal_size_t init_bytes = sizeof(malunal_int32_t) * 4;
const malunal_size_t final_bytes = sizeof(malunal_int32_t) * 8;
static
allocator_acquire_res_t
test_arena_acquires(allocator_mptr_t arena) {
allocator_acquire_res_t result =
allocator_acquire((allocator_acquire_req_t) {
.allocator = arena,
.size = init_bytes
});
if (result.threw)
return result;
// Upstream checks.
if (arena->upstream->reserved != page_bytes) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->reserved != %d, actual == %d";
fprintf(stderr, format, page_bytes, arena->upstream->reserved);
return (allocator_acquire_res_t) {
.threw = 1,
.exception = ALLOCATOR_EXCEPTION_FAILURE
};
}
if (arena->upstream->allocated != page_bytes) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->allocated != %d, actual == %d";
fprintf(stderr, format, page_bytes, arena->upstream->allocated);
return (allocator_acquire_res_t) {
.threw = 1,
.exception = ALLOCATOR_EXCEPTION_FAILURE
};
}
if (arena->upstream->acquires != 1) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->acquires != 1, actual == %d";
fprintf(stderr, format, arena->upstream->acquires);
return (allocator_acquire_res_t) {
.threw = 1,
.exception = ALLOCATOR_EXCEPTION_FAILURE
};
}
if (arena->upstream->releases != 0) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->releases != 0, actual == %d";
fprintf(stderr, format, arena->upstream->releases);
return (allocator_acquire_res_t) {
.threw = 1,
.exception = ALLOCATOR_EXCEPTION_FAILURE
};
}
// Arena checks.
if (arena->reserved != page_bytes) {
const malunal_cstr_t format =
"[arena_allocator]: arena->reserved != %d, actual == %d";
fprintf(stderr, format, page_bytes, arena->reserved);
return (allocator_acquire_res_t) {
.threw = 1,
.exception = ALLOCATOR_EXCEPTION_FAILURE
};
}
if (arena->allocated != init_bytes) {
const malunal_cstr_t format =
"[arena_allocator]: arena->allocated != %d, actual == %d";
fprintf(stderr, format, init_bytes, arena->allocated);
return (allocator_acquire_res_t) {
.threw = 1,
.exception = ALLOCATOR_EXCEPTION_FAILURE
};
}
if (arena->acquires != 1) {
const malunal_cstr_t format =
"[arena_allocator]: arena->acquires != 1, actual == %d";
fprintf(stderr, format, arena->acquires);
return (allocator_acquire_res_t) {
.threw = 1,
.exception = ALLOCATOR_EXCEPTION_FAILURE
};
}
if (arena->releases != 0) {
const malunal_cstr_t format =
"[arena_allocator]: arena->releases != 0, actual == %d";
fprintf(stderr, format, arena->releases);
return (allocator_acquire_res_t) {
.threw = 1,
.exception = ALLOCATOR_EXCEPTION_FAILURE
};
}
return result;
}
static int
test_arena_reacquire(
allocator_mptr_t arena,
malunal_mptr_t address
) {
malunal_int32_t index;
malunal_int32_t* vector;
vector = address;
for (index = 0; index < 4; index++)
vector[index] = index + 1;
allocator_acquire_res_t result =
allocator_reacquire((allocator_reacquire_req_t) {
.allocator = arena,
.prev = result.address,
.oldsz = init_bytes,
.newsz = final_bytes
});
if (result.threw)
return result.exception;
// Upstream checks.
if (arena->upstream->reserved != page_bytes) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->reserved != %d, actual == %d";
fprintf(stderr, format, page_bytes, arena->upstream->reserved);
return 1;
}
if (arena->upstream->allocated != page_bytes) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->allocated != %d, actual == %d";
fprintf(stderr, format, page_bytes, arena->upstream->allocated);
return 1;
}
if (arena->upstream->acquires != 1) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->acquires != 1, actual == %d";
fprintf(stderr, format, arena->upstream->acquires);
return 1;
}
if (arena->upstream->releases != 0) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->releases != 0, actual == %d";
fprintf(stderr, format, arena->upstream->releases);
return 1;
}
// Arena checks.
if (arena->reserved != page_bytes) {
const malunal_cstr_t format =
"[arena_allocator]: arena->reserved != %d, actual == %d";
fprintf(stderr, format, page_bytes, arena->reserved);
return 1;
}
malunal_int32_t all_bytes = init_bytes + final_bytes;
if (arena->allocated != all_bytes) {
const malunal_cstr_t format =
"[arena_allocator]: arena->allocated != %d, actual == %d";
fprintf(stderr, format, all_bytes, arena->allocated);
return 1;
}
if (arena->acquires != 2) {
const malunal_cstr_t format =
"[arena_allocator]: arena->acquires != 2, actual == %d";
fprintf(stderr, format, arena->acquires);
return 1;
}
if (arena->releases != 1) {
const malunal_cstr_t format =
"[arena_allocator]: arena->releases != 1, actual == %d";
fprintf(stderr, format, arena->releases);
return 1;
}
return ALLOCATOR_EXCEPTION_SUCCESS;
}
static int
test_arena_release(
allocator_mptr_t arena,
malunal_mptr_t address
) {
malunal_int32_t index;
malunal_int32_t* vector;
vector = address;
for (index = 0; index < 4; index++)
if (vector[index] != index + 1)
return 1;
allocator_exception_t relexc =
allocator_release((allocator_release_req_t) {
.allocator = arena,
.address = address,
.size = final_bytes
});
if (relexc != ALLOCATOR_EXCEPTION_SUCCESS)
return relexc;
// Upstream checks.
if (arena->upstream->reserved != page_bytes) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->reserved != %d, actual == %d";
fprintf(stderr, format, page_bytes, arena->upstream->reserved);
return 1;
}
if (arena->upstream->allocated != page_bytes) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->allocated != %d, actual == %d";
fprintf(stderr, format, page_bytes, arena->upstream->allocated);
return 1;
}
if (arena->upstream->acquires != 1) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->acquires != 1, actual == %d";
fprintf(stderr, format, arena->upstream->acquires);
return 1;
}
if (arena->upstream->releases != 0) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->releases != 0, actual == %d";
fprintf(stderr, format, arena->upstream->releases);
return 1;
}
// Arena checks.
if (arena->reserved != page_bytes) {
const malunal_cstr_t format =
"[arena_allocator]: arena->reserved != %d, actual == %d";
fprintf(stderr, format, page_bytes, arena->reserved);
return 1;
}
malunal_int32_t all_bytes = init_bytes + final_bytes;
if (arena->allocated != all_bytes) {
const malunal_cstr_t format =
"[arena_allocator]: arena->allocated != %d, actual == %d";
fprintf(stderr, format, all_bytes, arena->allocated);
return 1;
}
if (arena->acquires != 2) {
const malunal_cstr_t format =
"[arena_allocator]: arena->acquires != 2, actual == %d";
fprintf(stderr, format, arena->acquires);
return 1;
}
if (arena->releases != 2) {
const malunal_cstr_t format =
"[arena_allocator]: arena->releases != 2, actual == %d";
fprintf(stderr, format, arena->releases);
return 1;
}
return ALLOCATOR_EXCEPTION_SUCCESS;
}
static int
test_arena_reset(allocator_mptr_t arena) {
arena_reset(arena);
// Upstream checks.
if (arena->upstream->reserved != page_bytes) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->reserved != %d, actual == %d";
fprintf(stderr, format, page_bytes, arena->upstream->reserved);
return 1;
}
if (arena->upstream->allocated != page_bytes) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->allocated != %d, actual == %d";
fprintf(stderr, format, page_bytes, arena->upstream->allocated);
return 1;
}
if (arena->upstream->acquires != 1) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->acquires != 1, actual == %d";
fprintf(stderr, format, arena->upstream->acquires);
return 1;
}
if (arena->upstream->releases != 0) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->releases != 0, actual == %d";
fprintf(stderr, format, arena->upstream->releases);
return 1;
}
// Arena checks.
if (arena->reserved != page_bytes) {
const malunal_cstr_t format =
"[arena_allocator]: arena->reserved != %d, actual == %d";
fprintf(stderr, format, page_bytes, arena->reserved);
return 1;
}
if (arena->allocated != 0) {
const malunal_cstr_t format =
"[arena_allocator]: arena->allocated != 0, actual == %d";
fprintf(stderr, format, arena->allocated);
return 1;
}
if (arena->acquires != 2) {
const malunal_cstr_t format =
"[arena_allocator]: arena->acquires != 2, actual == %d";
fprintf(stderr, format, arena->acquires);
return 1;
}
if (arena->releases != 2) {
const malunal_cstr_t format =
"[arena_allocator]: arena->releases != 2, actual == %d";
fprintf(stderr, format, arena->releases);
return 1;
}
return ALLOCATOR_EXCEPTION_SUCCESS;
}
static int
test_arena_free(allocator_mptr_t arena) {
arena_free(arena);
// Upstream checks.
if (arena->upstream->reserved != 0) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->reserved != 0, actual == %d";
fprintf(stderr, format, arena->upstream->reserved);
return 1;
}
if (arena->upstream->allocated != 0) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->allocated != %d, actual == %d";
fprintf(stderr, format, arena->upstream->allocated);
return 1;
}
if (arena->upstream->acquires != 1) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->acquires != 1, actual == %d";
fprintf(stderr, format, arena->upstream->acquires);
return 1;
}
if (arena->upstream->releases != 1) {
const malunal_cstr_t format =
"[arena_allocator]: arena->upstream->releases != 1, actual == %d";
fprintf(stderr, format, arena->upstream->releases);
return 1;
}
// Arena checks.
if (arena->reserved != 0) {
const malunal_cstr_t format =
"[arena_allocator]: arena->reserved != %d, actual == %d";
fprintf(stderr, format, arena->reserved);
return 1;
}
if (arena->allocated != 0) {
const malunal_cstr_t format =
"[arena_allocator]: arena->allocated != 0, actual == %d";
fprintf(stderr, format, arena->allocated);
return 1;
}
if (arena->acquires != 2) {
const malunal_cstr_t format =
"[arena_allocator]: arena->acquires != 2, actual == %d";
fprintf(stderr, format, arena->acquires);
return 1;
}
if (arena->releases != 2) {
const malunal_cstr_t format =
"[arena_allocator]: arena->releases != 2, actual == %d";
fprintf(stderr, format, arena->releases);
return 1;
}
return ALLOCATOR_EXCEPTION_SUCCESS;
}
int test_arena_allocator() {
allocator_t upstream = platform_allocator();
allocator_t arena = arena_allocator(&upstream, page_bytes);
allocator_acquire_res_t result =
test_arena_acquires(&arena);
return !(
!result.threw &&
test_arena_reacquire(result.address, &arena) &&
test_arena_release(result.address, &arena) &&
test_arena_reset(&arena) &&
test_arena_free(&arena)
);
}