libc

my libc
git clone git://git.evenfri.pw/libc.git
Log | Files | Refs | README

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 }