aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas B. Rumbaugh <doug@douglasrumbaugh.com>2025-11-02 17:57:17 -0500
committerDouglas B. Rumbaugh <doug@douglasrumbaugh.com>2025-11-02 17:57:17 -0500
commit33be32d518e17c8f8971fa7c1fe09adcccd82a67 (patch)
treef283d00a8724dea295f43b4b626c428a570a1560
parentd22ffffb379ebda21bf792bf18ed9e1324e8902b (diff)
downloadliballoc-33be32d518e17c8f8971fa7c1fe09adcccd82a67.tar.gz
Added splitting and some basic testing for it
-rw-r--r--include/constants.h1
-rw-r--r--src/free_list.c17
-rw-r--r--tests/liballoc_tests.c30
3 files changed, 47 insertions, 1 deletions
diff --git a/include/constants.h b/include/constants.h
index 7d88060..8cb2db7 100644
--- a/include/constants.h
+++ b/include/constants.h
@@ -14,5 +14,6 @@
#define MAGIC_NUMBER 0x123456789
#define ALIGNMENT 16
+#define SPLIT_THRESHOLD 64
#endif
diff --git a/src/free_list.c b/src/free_list.c
index 11fb59b..6c0ff35 100644
--- a/src/free_list.c
+++ b/src/free_list.c
@@ -22,7 +22,22 @@ free_nd *fl_find_first_fit(free_nd *free_list, size_t size) {
}
void *fl_split_node(free_nd **free_list, free_nd *split_nd, size_t size) {
- /* for now, we'll just remove the node from the free list */
+
+ ssize_t extra_space = split_nd->size - size - sizeof(header);
+ if (extra_space >= SPLIT_THRESHOLD) {
+ free_nd *new_nd = (free_nd*)((char*) (split_nd) + size + sizeof(header));
+ new_nd->next = split_nd ->next;
+ split_nd->next = new_nd;
+
+ new_nd->size = extra_space - sizeof(header);
+
+ header *new_hdr = (header *)((char *)new_nd - sizeof(header));
+ new_hdr->magic_number = MAGIC_NUMBER;
+ new_hdr->size = extra_space - sizeof(header);
+
+ header *old_hdr = (header *)((char *)split_nd- sizeof(header));
+ old_hdr->size = size;
+ }
if (*free_list == split_nd) {
*free_list = (*free_list)->next;
diff --git a/tests/liballoc_tests.c b/tests/liballoc_tests.c
index 6e6b537..2d3a439 100644
--- a/tests/liballoc_tests.c
+++ b/tests/liballoc_tests.c
@@ -189,6 +189,34 @@ START_TEST(free_list_coalesce_backward) {
}
END_TEST
+START_TEST(free_list_split_basic) {
+ size_t initial_size = ALIGNMENT * 10;
+ size_t second_size = ALIGNMENT * 5;
+
+ void *memory = allocate(initial_size);
+ release(memory);
+
+ void *memory2 = allocate(second_size);
+ ck_assert_ptr_eq(memory, memory2);
+
+ ck_assert_ptr_nonnull(free_list_head());
+
+}
+END_TEST
+
+START_TEST(free_list_split_below_threshold) {
+ size_t initial_size = 5*ALIGNMENT;
+ size_t second_size = 2*ALIGNMENT;
+
+ void *memory = allocate(initial_size);
+ release(memory);
+
+ void *memory2 = allocate(second_size);
+ ck_assert_ptr_eq(memory, memory2);
+
+ ck_assert_ptr_null(free_list_head());
+}
+
Suite *liballoc_suite(void) {
@@ -207,6 +235,8 @@ Suite *liballoc_suite(void) {
tcase_add_test(unit, free_list_reuse);
tcase_add_test(unit, free_list_coalesce_forward);
tcase_add_test(unit, free_list_coalesce_backward);
+ tcase_add_test(unit, free_list_split_basic);
+ tcase_add_test(unit, free_list_split_below_threshold);
suite_add_tcase(s, unit);
return s;