/* * src/alloc.c * * Primary implementation of allocator logic for liballoc * CISC 301 -- Operating Systems, Project 3 * * Copyright (C) 2025 Douglas B. Rumbaugh * * Distributed under the Modified BSD License * */ #include "alloc.h" #include "constants.h" #include "free_list.h" #include "alloc_header.h" static void *heap_start = 0; static void *heap_end = 0; free_nd *free_list = NULL; static void initialize() { heap_start = sbrk(0); if (heap_start == (void *)-1) { perror("liballoc initialization:"); exit(EXIT_FAILURE); } size_t padding = (size_t)heap_start % ALIGNMENT; if (padding) { heap_start = sbrk(padding); if (heap_start == (void *)-1) { perror("liballoc initialization:"); exit(EXIT_FAILURE); } } assert((size_t)heap_start % ALIGNMENT == 0); heap_end = heap_start; } void *allocate(size_t size) { if (!heap_start) { initialize(); } /* * pad the requested size to ensure alignment using * the alignment one-liner we discussed in class */ size = (size + ALIGNMENT - 1) & ~(ALIGNMENT - 1); /* first check for a suitable memory block on the free list */ free_nd *nd = fl_find_first_fit(free_list, size); if (nd) { void *return_region = fl_split_node(&free_list, nd, size); } /* * if there aren't any blocks on the free list, we need to allocate * from scratch */ void *new_region = sbrk(size + sizeof(header)); /* out of memory */ if (new_region == (void *)-1) { return NULL; } heap_end = new_region + size + sizeof(header); ((header *)new_region)->size = size; ((header *)new_region)->magic_number = MAGIC_NUMBER; return new_region + sizeof(header); } void release(void *ptr) { fl_add_node(&free_list, ptr); fl_coalesce_nodes(free_list); }