Skip to content

Commit

Permalink
Add buddy_arena_free_size
Browse files Browse the repository at this point in the history
  • Loading branch information
spaskalev committed Mar 19, 2023
1 parent ebf6868 commit 2ff32d9
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 0 deletions.
24 changes: 24 additions & 0 deletions buddy_alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ unsigned int buddy_is_full(struct buddy *buddy);
/* Reports the arena size */
size_t buddy_arena_size(struct buddy *buddy);

/* Reports the arena's free size. Note that this is (often) not a continuous size
but the sum of all free slots in the buddy. */
size_t buddy_arena_free_size(struct buddy *buddy);

/*
* Allocation functions
*/
Expand Down Expand Up @@ -547,6 +551,26 @@ size_t buddy_arena_size(struct buddy *buddy) {
return buddy->memory_size;
}

size_t buddy_arena_free_size(struct buddy *buddy) {
size_t result = 0;
struct buddy_tree *tree = buddy_tree(buddy);
size_t tree_order = buddy_tree_order(tree);

struct buddy_tree_walk_state state = buddy_tree_walk_state_root();
do {
size_t pos_status = buddy_tree_status(tree, state.current_pos);
if (pos_status == (tree_order - state.current_pos.depth + 1)) { // Fully-allocated
state.going_up = 1;
} else if (pos_status == 0) { // Free
state.going_up = 1;
result += size_for_depth(buddy, state.current_pos.depth);
} else { // Partial
continue;
}
} while (buddy_tree_walk(tree, &state));
return result;
}

static size_t buddy_tree_order_for_memory(size_t memory_size) {
size_t blocks = memory_size / BUDDY_ALLOC_ALIGN;
return highest_bit_position(ceiling_power_of_two(blocks));
Expand Down
40 changes: 40 additions & 0 deletions tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,43 @@ void test_buddy_arena_size() {
assert(buddy_arena_size(buddy) == 4096);
}

void test_buddy_arena_free_size_01() {
start_test;
unsigned char *buddy_buf = malloc(buddy_sizeof(4096));
unsigned char data_buf[4096];
struct buddy *buddy = buddy_init(buddy_buf, data_buf, 4096);
assert(buddy_arena_free_size(buddy) == 4096);
void *slot = buddy_malloc(buddy, 4096);
assert(buddy_arena_free_size(buddy) == 0);
buddy_free(buddy, slot);
assert(buddy_arena_free_size(buddy) == 4096);
free(buddy_buf);
}

void test_buddy_arena_free_size_02() {
start_test;
unsigned char *buddy_buf = malloc(buddy_sizeof(4096));
unsigned char data_buf[4096];
struct buddy *buddy = buddy_init(buddy_buf, data_buf, 3072);
assert(buddy_arena_free_size(buddy) == 3072);
void *slot = buddy_malloc(buddy, 2048);
assert(buddy_arena_free_size(buddy) == 1024);
buddy_free(buddy, slot);
assert(buddy_arena_free_size(buddy) == 3072);
free(buddy_buf);
}

void test_buddy_arena_free_size_03() {
start_test;
unsigned char shared_buf[8192];
struct buddy *buddy = buddy_embed(shared_buf, 8192);
size_t current_free = buddy_arena_free_size(buddy);
void *slot = buddy_malloc(buddy, 2048);
assert(buddy_arena_free_size(buddy) == current_free - 2048);
buddy_free(buddy, slot);
assert(buddy_arena_free_size(buddy) == current_free);
}

void test_buddy_malloc_null() {
start_test;
assert(buddy_malloc(NULL, 1024) == NULL);
Expand Down Expand Up @@ -2061,6 +2098,9 @@ int main() {

test_buddy_can_shrink();
test_buddy_arena_size();
test_buddy_arena_free_size_01();
test_buddy_arena_free_size_02();
test_buddy_arena_free_size_03();

test_buddy_malloc_null();
test_buddy_malloc_zero();
Expand Down

0 comments on commit 2ff32d9

Please sign in to comment.