26 X("mm::allocation", test_mm_allocation), X("mm::block_allocation", test_mm_allocation_in_block), \
27 X("mm::multiblock_allocation", test_mm_allocation_multiblock), \
28 X("mm::block_bitmap", test_mm_block_bitmap), \
29 X("mm::block_size_properties", test_mm_block_size_properties), \
30 X("mm::aligned_block_allocation", test_mm_aligned_block_allocation), \
31 X("mm::immortal_multiblock", test_mm_immortal_multiblock), \
32 X("mm::get_block_out_of_range", test_mm_get_block_out_of_range), \
33 X("mm::block_release_reuse", test_mm_block_release_reuse), \
34 X("mm::get_block_after_release", test_mm_get_block_after_release), \
35 X("mm::over_aligned_allocation", test_mm_over_aligned_allocation)
38# define MM_TEST_LOG(...) DBG("MM_TEST", __VA_ARGS__)
40# define MM_TEST_LOG(...)
52static inline size_t padding(
size_t size,
size_t align) {
53 return (align - (size & (align - 1U))) & (align - 1);
62 for (
int i = 0; i < 200; i++) {
79 for (
int i = 0; i < 200; i++) {
101 for (
int i = 0; i < 0xffff; i++) {
106 for (
int i = 0; i < 0xffff; i++) {
113 for (
int i = 0; i < 200; i++) {
142 for (
int i = 0; i < 4; i++) {
150 MM_TEST_LOG(
"Allocated block ids: %zu, %zu, %zu", (
size_t)b0, (
size_t)b1, (
size_t)b2);
186 MM_TEST_LOG(
"Allocated block id for aligned test: %zu", (
size_t)b);
188 size_t alignment = 32;
194 MM_TEST_LOG(
"Aligned allocations: p1=%p, p2=%p", p1, p2);
207 uintptr_t base = (uintptr_t)&block->
base;
210 TEST_CHECK((uintptr_t)p1 >= base && (uintptr_t)p1 + size <= end);
211 TEST_CHECK((uintptr_t)p2 >= base && (uintptr_t)p2 + size <= end);
221 MM_TEST_LOG(
"Allocating mm_64k instances in immortal block");
231 for (
int i = 0; i < 0xffff; i++) {
241 MM_TEST_LOG(
"immortal root = %p, next = %p", (
void *)root, (
void *)root->
next);
292 for (
size_t alignment = 32; alignment <= 256; alignment *= 2) {
295 TEST_MSG(
"alignment %zu, remainder %zu", alignment, (
size_t)((uintptr_t)p % alignment));
#define ASSERT_NOT_NULL(x)
#define SRN_CONFIG_DEFAULT_BLOCK_SIZE
The default block size in bytes, derived from the magnitude.
#define SRN_CONFIG_DEFAULT_BLOCK_SIZE_MAGNITUDE
Magnitude of one memory-manager block.
size_t srn_block_id_t
The block id is effectively just an index in the blocks array in srn_mm_t.
void srn_mm_release_block(srn_mm_t *mm, srn_block_id_t id)
Release the given block id and free the memory for later allocations.
void * srn_mm_allocate_in_block_aligned(srn_mm_t *mm, srn_block_id_t block_id, size_t size, size_t alignment)
Allocate memory on a block with the given block_id.
srn_block_t * srn_mm_get_block(srn_mm_t *mm, srn_block_id_t block_id)
Return the block object associated by the given block_id.
srn_block_id_t srn_mm_allocate_block(srn_mm_t *mm)
Allocate a new block in the memory manager and return its ID.
size_t srn_mm_get_os_page_size(void)
Retutrns the OS page size.
void srn_mm_shutdown(srn_mm_t *mm)
Shut down the memory manager and release the resources.
srn_mm_t * srn_mm_init(const srn_configuration_t *config)
Initialize the memory manager, this function will panic on error.
#define srn_mm_immortal_allocate(mm, T)
#define srn_mm_allocate_in_block(mm, id, T)
#define MAX_NUMBER_OF_BLOCKS
array of blocks is enough for us, we can tweak the size as we see fit.
static void test_mm_allocation()
static void test_mm_immortal_multiblock(void)
static void test_mm_block_bitmap(void)
static void test_mm_allocation_in_block()
static void test_mm_block_size_properties(void)
static void test_mm_block_release_reuse(void)
Block ids are reused after release, so a release must also retire every piece of allocation bookkeepi...
static void test_mm_aligned_block_allocation(void)
static void test_mm_over_aligned_allocation(void)
Alignments above DEFAULT_BLOCK_ALIGNMENT must be honored on the returned pointer.
static void test_mm_get_block_after_release(void)
A released id must not resolve to a block anymore.
static size_t padding(size_t size, size_t align)
static void test_mm_allocation_multiblock()
static void test_mm_get_block_out_of_range(void)
uint8_t base[]
Where the data area starts.
size_t size
This is the TOTAL size of the block, header + payloud.
struct srn_block_t * next
when the block does not have space to allocate a request, we will allocate a new block and point to i...
Main memory manager structure that will own all the allocated blocks and data.
srn_block_t * immortal_block
Immortal block is a chain of blocks which will never die.
uint64_t block_bitmap[4]
This is a 256bit bitmap we treat it as a whole.