/* * src/free_list.c * * Implementation of free list management for liballoc * CISC 301 -- Operating Systems, Project 3 * * Copyright (C) 2025 Douglas B. Rumbaugh * * Distributed under the Modified BSD License * */ #include "free_list.h" free_nd *fl_find_first_fit(free_nd *free_list, size_t size) { for (free_nd *nd = free_list; nd; nd = nd->next) { if (nd->size >= size) { return nd; } } return NULL; } 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 */ if (*free_list == split_nd) { *free_list = (*free_list)->next; } for (free_nd *nd = *free_list; nd; nd = nd->next) { if (nd->next == split_nd) { /* * split_nd is not null, so we know that nd->next is * also not null here */ nd->next = nd->next->next; } } return split_nd; } void fl_coalesce_nodes(free_nd *free_list) { for (free_nd *nd = free_list; nd; nd = nd->next) { if ((size_t)nd + sizeof(header) == (size_t)nd->next) { nd->size += sizeof(header) + nd->next->size; nd->next = nd->next->next; } } } void fl_add_node(free_nd **free_list, void *ptr) { free_nd *new_nd = (free_nd *)ptr; new_nd->next = NULL; new_nd->size = ((header*)(ptr - sizeof(header)))->size; if (!(*free_list)) { *free_list = new_nd; return; } for (free_nd *nd = *free_list; nd; nd = nd->next) { if (nd->next > new_nd) { new_nd->next = nd->next; nd->next = new_nd; return; } } /* if we get here, then the new node must go before the current head */ new_nd->next = *free_list; *free_list = new_nd; return; }