176 lines
5.7 KiB
C
176 lines
5.7 KiB
C
#include "malunal/allocators/arena.h"
|
|
#include "malunal/microtest.h"
|
|
|
|
MICROTEST(arena_allocator, can_init_and_free) {
|
|
error_t result = {};
|
|
arena_allocator_t allocator = {};
|
|
malunal_uint32_t temporary = 0;
|
|
|
|
result = arena_allocator_init(500, &allocator);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
|
|
result = arena_allocator_size(&allocator, &temporary);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(temporary, platform_page_size());
|
|
|
|
result = arena_allocator_used(&allocator, &temporary);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(temporary, 16);
|
|
|
|
result = arena_allocator_free(&allocator);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
|
|
result = arena_allocator_size(&allocator, &temporary);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(temporary, 0);
|
|
|
|
result = arena_allocator_used(&allocator, &temporary);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(temporary, 0);
|
|
}
|
|
|
|
MICROTEST(arena_allocator, can_acquire_and_dispose) {
|
|
error_t result = {};
|
|
arena_allocator_t allocator = {};
|
|
malunal_mptr_t address = null;
|
|
malunal_uint32_t temporary = 0;
|
|
|
|
arena_allocator_init(500, &allocator);
|
|
result = arena_allocator_acquire(&allocator, 64, &address);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_ASSERT_NOT_NULL(address);
|
|
|
|
result = arena_allocator_used(&allocator, &temporary);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(temporary, 80);
|
|
|
|
result = arena_allocator_dispose(&allocator, address, 64);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
|
|
result = arena_allocator_used(&allocator, &temporary);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(temporary, 80);
|
|
arena_allocator_free(&allocator);
|
|
}
|
|
|
|
MICROTEST(arena_allocator, can_reset_allocator) {
|
|
error_t result = {};
|
|
arena_allocator_t allocator = {};
|
|
malunal_mptr_t address = null;
|
|
malunal_uint32_t temporary = 0;
|
|
|
|
arena_allocator_init(500, &allocator);
|
|
result = arena_allocator_acquire(&allocator, 64, &address);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_ASSERT_NOT_NULL(address);
|
|
|
|
result = arena_allocator_used(&allocator, &temporary);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(temporary, 80);
|
|
|
|
result = arena_allocator_reset(&allocator);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
|
|
result = arena_allocator_used(&allocator, &temporary);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(temporary, 16);
|
|
arena_allocator_free(&allocator);
|
|
}
|
|
|
|
MICROTEST(arena_allocator, can_acquire_beyond_first_region) {
|
|
arena_allocator_t allocator = {};
|
|
malunal_mptr_t addresses[256];
|
|
malunal_uint32_t temporary = 0;
|
|
|
|
arena_allocator_init(500, &allocator);
|
|
for (malunal_size_t index = 0; index < 256; index++) {
|
|
error_t result = arena_allocator_acquire(&allocator, 64, &addresses[index]);
|
|
MICROTEST_ASSERT_NULL(result.domain);
|
|
memset(addresses[index], (int)index, 64);
|
|
}
|
|
|
|
for (malunal_size_t index = 0; index < 256; index++) {
|
|
malunal_uint8_t* bytes = addresses[index];
|
|
MICROTEST_EXPECT_EQ(bytes[63], (malunal_uint8_t)index);
|
|
}
|
|
|
|
arena_allocator_size(&allocator, &temporary);
|
|
MICROTEST_EXPECT_GT(temporary, platform_page_size());
|
|
arena_allocator_free(&allocator);
|
|
}
|
|
|
|
MICROTEST(arena_allocator, can_acquire_larger_than_region) {
|
|
arena_allocator_t allocator = {};
|
|
malunal_mptr_t address = null;
|
|
malunal_size_t size = platform_page_size() * 3;
|
|
|
|
arena_allocator_init(500, &allocator);
|
|
error_t result = arena_allocator_acquire(&allocator, size, &address);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_ASSERT_NOT_NULL(address);
|
|
|
|
memset(address, 0xAB, size);
|
|
arena_allocator_free(&allocator);
|
|
}
|
|
|
|
MICROTEST(arena_allocator, oversized_request_reports_out_of_memory) {
|
|
arena_allocator_t allocator = {};
|
|
malunal_mptr_t address = null;
|
|
|
|
arena_allocator_init(500, &allocator);
|
|
error_t result = arena_allocator_acquire(&allocator, (malunal_size_t)-1, &address);
|
|
MICROTEST_EXPECT_NOT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(result.code, (malunal_int32_t)ALLOCATOR_ERROR_OUT_OF_MEMORY);
|
|
arena_allocator_free(&allocator);
|
|
}
|
|
|
|
MICROTEST(arena_allocator, acquisitions_are_aligned) {
|
|
arena_allocator_t allocator = {};
|
|
|
|
arena_allocator_init(500, &allocator);
|
|
for (malunal_size_t size = 1; size <= 33; size += 3) {
|
|
malunal_mptr_t address = null;
|
|
arena_allocator_acquire(&allocator, size, &address);
|
|
MICROTEST_EXPECT_EQ((malunal_uintptr_t)address % 16, (malunal_uintptr_t)0);
|
|
}
|
|
|
|
arena_allocator_free(&allocator);
|
|
}
|
|
|
|
MICROTEST(arena_allocator, can_dispose_from_later_region) {
|
|
arena_allocator_t allocator = {};
|
|
malunal_mptr_t address = null;
|
|
|
|
arena_allocator_init(500, &allocator);
|
|
for (malunal_size_t index = 0; index < 128; index++)
|
|
arena_allocator_acquire(&allocator, 64, &address);
|
|
|
|
error_t result = arena_allocator_dispose(&allocator, address, 64);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
arena_allocator_free(&allocator);
|
|
}
|
|
|
|
MICROTEST(arena_allocator, dispose_rejects_foreign_address) {
|
|
arena_allocator_t allocator = {};
|
|
malunal_uint8_t foreign[64];
|
|
|
|
arena_allocator_init(500, &allocator);
|
|
error_t result = arena_allocator_dispose(&allocator, foreign, sizeof(foreign));
|
|
MICROTEST_EXPECT_NOT_NULL(result.domain);
|
|
MICROTEST_EXPECT_EQ(result.code, (malunal_int32_t)ALLOCATOR_ERROR_NOT_MY_ADDRESS);
|
|
arena_allocator_free(&allocator);
|
|
}
|
|
|
|
MICROTEST(arena_allocator, can_acquire_after_free) {
|
|
arena_allocator_t allocator = {};
|
|
malunal_mptr_t address = null;
|
|
|
|
arena_allocator_init(500, &allocator);
|
|
arena_allocator_free(&allocator);
|
|
|
|
error_t result = arena_allocator_acquire(&allocator, 64, &address);
|
|
MICROTEST_EXPECT_NULL(result.domain);
|
|
MICROTEST_ASSERT_NOT_NULL(address);
|
|
arena_allocator_free(&allocator);
|
|
}
|