libc

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

malloc.c (1398B)


      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 
     11 struct block_header {
     12   size_t size;
     13   int is_free;
     14   struct block_header *next;
     15 } __attribute__((aligned(16)));
     16 
     17 typedef struct block_header block_header_t;
     18 
     19 static block_header_t *free_list = NULL;
     20 
     21 static size_t align(size_t n) {
     22   return (n + ALIGN_MASK) & ~ALIGN_MASK;
     23 }
     24 
     25 void* malloc(size_t size) {
     26   if (size == 0) {
     27     return NULL;
     28   }
     29 
     30   size_t total_size = align(size + sizeof(block_header_t));
     31   block_header_t *curr =  free_list;
     32   block_header_t *prev = NULL;
     33 
     34   while (curr != NULL) {
     35     if (curr->is_free && curr->size >= total_size) {
     36       curr->is_free = 0;
     37       return (void*)(curr + 1);
     38     }
     39     prev = curr;
     40     curr = curr->next;
     41   }
     42 
     43   size_t alloc_size = total_size < 4096 ? 4096 : total_size;
     44   block_header_t *block = mmap(NULL, alloc_size,
     45       PROT_READ | PROT_WRITE,
     46       MAP_PRIVATE | MAP_ANONYMOUS,
     47       -1, 0);
     48 
     49   if (block == MAP_FAILED) {
     50     return NULL;
     51   }
     52 
     53   block->size = alloc_size;
     54   block->is_free = 0;
     55   block->next = NULL;
     56 
     57   if (prev != NULL) {
     58     prev->next = block;
     59   } else {
     60     free_list = block;
     61   }
     62 
     63   return (void*)(block + 1);
     64 }
     65 
     66 void free(void *ptr) {
     67   if (ptr == NULL) {
     68     return;
     69   }
     70 
     71   block_header_t *header = (block_header_t*)ptr - 1;
     72   header->is_free = 1;
     73 }