#include <libarena/common.h>
#include <libarena/asan.h>
#include <libarena/buddy.h>
extern struct buddy __arena buddy;
struct segarr_entry {
u8 __arena *block;
size_t sz;
u8 poison;
};
#define SEGARRLEN (512)
static struct segarr_entry __arena segarr[SEGARRLEN];
static void __arena *ptrs[17];
size_t __arena alloc_sizes[] = { 3, 17, 1025, 129, 16350, 333, 9, 517 };
size_t __arena alloc_multiple_sizes[] = { 3, 17, 1025, 129, 16350, 333, 9, 517, 2099 };
size_t __arena alloc_free_sizes[] = { 3, 17, 64, 129, 256, 333, 512, 517 };
size_t __arena alignment_sizes[] = { 1, 3, 7, 8, 9, 15, 16, 17, 31,
32, 64, 100, 128, 255, 256, 512, 1000 };
SEC("syscall")
__weak int test_buddy_create(void)
{
const int iters = 10;
int ret, i;
for (i = zero; i < iters && can_loop; i++) {
ret = buddy_init(&buddy);
if (ret)
return ret;
ret = buddy_destroy(&buddy);
if (ret)
return ret;
}
return 0;
}
SEC("syscall")
__weak int test_buddy_alloc(void)
{
void __arena *mem;
int ret, i;
for (i = zero; i < 8 && can_loop; i++) {
ret = buddy_init(&buddy);
if (ret)
return ret;
mem = buddy_alloc(&buddy, alloc_sizes[i]);
if (!mem) {
buddy_destroy(&buddy);
return -ENOMEM;
}
buddy_destroy(&buddy);
}
return 0;
}
SEC("syscall")
__weak int test_buddy_alloc_free(void)
{
const int iters = 800;
void __arena *mem;
int ret, i;
ret = buddy_init(&buddy);
if (ret)
return ret;
for (i = zero; i < iters && can_loop; i++) {
mem = buddy_alloc(&buddy, alloc_free_sizes[(i * 5) % 8]);
if (!mem) {
buddy_destroy(&buddy);
return -ENOMEM;
}
buddy_free(&buddy, mem);
}
buddy_destroy(&buddy);
return 0;
}
SEC("syscall")
__weak int test_buddy_alloc_multiple(void)
{
int ret, j;
u32 i, idx;
u8 __arena *mem;
size_t sz;
u8 poison;
ret = buddy_init(&buddy);
if (ret)
return ret;
for (i = zero; i < SEGARRLEN && can_loop; i++) {
sz = alloc_multiple_sizes[i % 9];
poison = (u8)i;
mem = buddy_alloc(&buddy, sz);
if (!mem) {
buddy_destroy(&buddy);
arena_stdout("%s:%d", __func__, __LINE__);
return -ENOMEM;
}
segarr[i].block = mem;
segarr[i].sz = sz;
segarr[i].poison = poison;
for (j = zero; j < sz && can_loop; j++) {
mem[j] = poison;
if (mem[j] != poison) {
buddy_destroy(&buddy);
return -EINVAL;
}
}
}
for (i = 10; i < SEGARRLEN && can_loop; i++) {
idx = (i * 17) % SEGARRLEN;
mem = segarr[idx].block;
sz = segarr[idx].sz;
poison = segarr[idx].poison;
for (j = zero; j < sz && can_loop; j++) {
if (mem[j] != poison) {
buddy_destroy(&buddy);
arena_stdout("%s:%d %lx %u vs %u", __func__,
__LINE__, (uintptr_t)&mem[j],
mem[j], poison);
return -EINVAL;
}
}
buddy_free(&buddy, mem);
}
buddy_destroy(&buddy);
return 0;
}
SEC("syscall")
__weak int test_buddy_alignment(void)
{
int ret, i;
ret = buddy_init(&buddy);
if (ret)
return ret;
for (i = zero; i < 17 && can_loop; i++) {
ptrs[i] = buddy_alloc(&buddy, alignment_sizes[i]);
if (!ptrs[i]) {
arena_stdout("alignment test: alloc failed for size %lu",
alignment_sizes[i]);
buddy_destroy(&buddy);
return -ENOMEM;
}
if ((u64)ptrs[i] & 0x7) {
arena_stdout(
"alignment test: ptr %llx not 8-byte aligned (size %lu)",
(u64)ptrs[i], alignment_sizes[i]);
buddy_destroy(&buddy);
return -EINVAL;
}
}
for (i = zero; i < 17 && can_loop; i++)
buddy_free(&buddy, ptrs[i]);
buddy_destroy(&buddy);
return 0;
}
__weak char _license[] SEC("license") = "GPL";