malloc.c (1598B)
1 /* 2 * malloc.c - basic memory allocator 3 * Copyright (C) 2026. All rights reserved. 4 */ 5 6 #include "libc.h" 7 8 #define ALIGN_SIZE 16 9 #define ALIGN_MASK (ALIGN_SIZE - 1) 10 #define MIN_ALLOC_SIZE 4096 11 12 static block_header_t *free_list = NULL; 13 14 static int align_size(size_t n, size_t *result) { 15 if (n > (size_t)-1 - ALIGN_MASK) { 16 return -1; 17 } 18 19 *result = (n + ALIGN_MASK) & ~ALIGN_MASK; 20 return 0; 21 } 22 23 void* malloc(size_t size) { 24 if (size == 0) { 25 return NULL; 26 } 27 28 if (size > (size_t)-1 - sizeof(block_header_t)) { 29 return NULL; 30 } 31 32 size_t total_size; 33 if (align_size(size + sizeof(block_header_t), &total_size) < 0) { 34 return NULL; 35 } 36 37 block_header_t *curr = free_list; 38 block_header_t *prev = NULL; 39 40 while (curr != NULL) { 41 if (curr->is_free && curr->size >= total_size) { 42 curr->is_free = 0; 43 curr->requested_size = size; 44 return (void*)(curr + 1); 45 } 46 prev = curr; 47 curr = curr->next; 48 } 49 50 size_t alloc_size = total_size < MIN_ALLOC_SIZE ? MIN_ALLOC_SIZE : total_size; 51 block_header_t *block = mmap(NULL, alloc_size, 52 PROT_READ | PROT_WRITE, 53 MAP_PRIVATE | MAP_ANONYMOUS, 54 -1, 0); 55 56 if (block == MAP_FAILED) { 57 return NULL; 58 } 59 60 block->size = alloc_size; 61 block->requested_size = size; 62 block->is_free = 0; 63 block->next = NULL; 64 65 if (prev != NULL) { 66 prev->next = block; 67 } else { 68 free_list = block; 69 } 70 71 return (void*)(block + 1); 72 } 73 74 void free(void *ptr) { 75 if (ptr == NULL) { 76 return; 77 } 78 79 block_header_t *header = (block_header_t*)ptr - 1; 80 header->is_free = 1; 81 header->requested_size = 0; 82 }