From b4f942f678dc63a433ef2f2b774b8429a0d54e71 Mon Sep 17 00:00:00 2001 From: Guillem George Date: Fri, 7 Nov 2025 20:29:21 +0100 Subject: [PATCH] backup --- malloc/Makefile | 6 +-- malloc/src/helpers/allocate.c | 70 +++++++++++++++++++++++++++++++++++ malloc/src/helpers/allocate.h | 13 +++++++ malloc/src/helpers/helpers.c | 68 +++++++++++++++++++++++----------- malloc/src/helpers/helpers.h | 19 ++++++---- malloc/src/malloc.c | 35 +++++++++++++++--- 6 files changed, 174 insertions(+), 37 deletions(-) create mode 100644 malloc/src/helpers/allocate.c create mode 100644 malloc/src/helpers/allocate.h diff --git a/malloc/Makefile b/malloc/Makefile index 6334b0d..2ee592b 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -1,10 +1,10 @@ CC=gcc CFLAGS=-std=c99 -pedantic -Werror -Wall -Wextra -Wvla -fvisibility=hidden -fPIC -CPPFLAGS=D_DEFAULT_SOURCE +CPPFLAGS= -D_DEFAULT_SOURCE LDFLAGS= -shared -Wl --no-undefined -SRCS= -OBJS=${SRC:.c=.o} +SRCS=src/malloc.c src/helpers/helpers.c src/helpers/allocate.c +OBJS=${SRCS:.c=.o} TARGET=libmalloc.so library: $(OBJS) diff --git a/malloc/src/helpers/allocate.c b/malloc/src/helpers/allocate.c new file mode 100644 index 0000000..9c8739f --- /dev/null +++ b/malloc/src/helpers/allocate.c @@ -0,0 +1,70 @@ +#include "allocate.h" + +#include +#include + +#include "helpers.h" + +void *allocate_block(struct bucket *biquette, int block_number) +{ + if (block_number == -1) + return NULL; + + // Update header + unsigned char byte_mask = 1 << ((block_number % 8) - 1); + biquette->alloc_blk_cnt++; + biquette->free_map[block_number / 8] &= byte_mask; + + // Compute block address + return get_block(biquette, block_number); +} + +struct bucket *create_bucket(size_t min_alloc_size) +{ + // Round up + size_t alloc_size; + if (min_alloc_size > PAGE_SIZE - sizeof(struct bucket)) + // Huge page + alloc_size = min_alloc_size; + else + // Regular page + alloc_size = s2p(min_alloc_size); + + // Get page + void *page = + mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, -1, 0); + + if (page == NULL) + return NULL; + + // Init bucket + struct bucket *header = page; + header->block_size = alloc_size; + header->alloc_blk_cnt = 0; + memset(header->free_map, 0, FREE_LIST_SIZE); + + return header; +} + +void free_block(void *ptr, struct bucket **list) +{ + // Compute header location and block number + struct bucket *header = get_page_begin(ptr); + + // free in map and update size + int block_number; // ... + unsigned char byte_mask = 1 << ((block_number % 8) - 1); + header->free_map[block_number / 8] &= ~byte_mask; + + // Huge page + if (header->block_size > BUCKET_SIZE) + // Delete bucket + header->alloc_blk_cnt = 0; + + // free bucket if necessary + if (header->alloc_blk_cnt == 0) + { + bucket_list_remove(list, header); + munmap(ptr, 1); + } +} diff --git a/malloc/src/helpers/allocate.h b/malloc/src/helpers/allocate.h new file mode 100644 index 0000000..3e91a0e --- /dev/null +++ b/malloc/src/helpers/allocate.h @@ -0,0 +1,13 @@ +#ifndef ALLOCATE_H +#define ALLOCATE_H + +#include "helpers.h" + +#include + +void *allocate_block(struct bucket *biquette, int block_number); +struct bucket *create_bucket(size_t min_alloc_size); +void bucket_append(struct bucket **head, struct bucket *elt); +void free_block(void *ptr, struct bucket **list); + +#endif // ! ALLOCATE_H diff --git a/malloc/src/helpers/helpers.c b/malloc/src/helpers/helpers.c index df0e7fa..8091eda 100644 --- a/malloc/src/helpers/helpers.c +++ b/malloc/src/helpers/helpers.c @@ -1,8 +1,5 @@ #include "helpers.h" -#include -#include - // Returns the smallest power of 2 greater or equal to s size_t s2p(size_t s) { @@ -33,44 +30,47 @@ size_t s2p(size_t s) return n; } -void *find_free_block(struct bucket *buck) +int find_free_block(struct bucket *buck) { - unsigned maplength = buck->block_size / 8; + unsigned maplength = PAGE_SIZE / buck->block_size / 8; // for each block for (unsigned i = 0; i < maplength; i++) { - unsigned char map_byte = buck->free_list[i]; + unsigned char map_byte = buck->free_map[i]; unsigned char bit = 1; // Test byte for (unsigned j = 0; j < 8; j <<= 1) { if (map_byte & bit) // Test if free - return get_data_begin(buck) + (buck->block_size * (i * 8 + j)); + return i * 8 + j; bit <<= 1; } } - return NULL; + return -1; } -struct bucket *create_bucket(size_t min_alloc_size) +void *get_block(struct bucket *biquette, int block_number) { - // Round up - size_t alloc_size = s2p(min_alloc_size); - // Get page - void *page = - mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, -1, 0); - - if (page == NULL) + if (block_number == -1) return NULL; - // Init bucket - struct bucket *header = page; - header->block_size = alloc_size; - memset(header->free_list, 0, FREE_LIST_SIZE); + char *data_begin = get_data_begin(biquette); + return data_begin + (biquette->block_size * (block_number)); +} - return header; +int get_block_number(struct bucket *biquette, void *block) +{ + if (block == NULL || biquette == NULL) + return -1; + + char *block_nul = block; + void *biquetteounette = biquette; + char *biquette_cherie = biquetteounette; + + return (block_nul - biquette_cherie - sizeof(struct bucket)) + / biquette->block_size; } // Gets a bucket with at least a block_size of size @@ -99,7 +99,7 @@ void *get_page_begin(void *ptr) return pointeur_alacon + quelenfer; } -void bucket_append(struct bucket **head, struct bucket *elt) +void bucket_list_append(struct bucket **head, struct bucket *elt) { struct bucket *list_elt = *head; if (list_elt == NULL) @@ -114,3 +114,27 @@ void bucket_append(struct bucket **head, struct bucket *elt) } list_elt->next = elt; } + +// Removes a bucket from the list pointed by head +void bucket_list_remove(struct bucket **head, struct bucket *elt) +{ + struct bucket *list_elt = *head; + if (list_elt == NULL) + return; + + if (*head == elt) + { + *head = NULL; + return; + } + + while (list_elt->next != NULL) + { + if (list_elt->next == elt) + { + list_elt->next = list_elt->next->next; + return; + } + list_elt = list_elt->next; + } +} diff --git a/malloc/src/helpers/helpers.h b/malloc/src/helpers/helpers.h index 217f7e9..ec8bd0b 100644 --- a/malloc/src/helpers/helpers.h +++ b/malloc/src/helpers/helpers.h @@ -1,7 +1,7 @@ #ifndef HELPERS_H #define HELPERS_H -// #define PAGE_SIZE (size_t) sysconf(_SC_PAGE_SIZE) +// #define PAGE_SIZE sysconf(_SC_PAGE_SIZE) #define PAGE_SIZE 4096 #define MIN_BLOCK_SIZE 8 #define FREE_LIST_SIZE PAGE_SIZE / MIN_BLOCK_SIZE / sizeof(unsigned char) @@ -13,19 +13,24 @@ struct bucket { unsigned block_size; - unsigned char free_list[FREE_LIST_SIZE]; // 4096 / MIN_BLOCK_SIZE / - // sizeof(unsigned char) + unsigned char free_map[FREE_LIST_SIZE]; // Keeps track of allocations + // If block_size > MIN_BLOCK_SIZE + // It will use a consecutive + // representation + unsigned short alloc_blk_cnt; // Counts the number of allocated blocks struct bucket *next; - size_t checksum; }; +#define BUCKET_SIZE PAGE_SIZE - sizeof(struct bucket) + size_t s2p(size_t n); -void *find_free_block(struct bucket *buck); -struct bucket *create_bucket(size_t min_alloc_size); +int find_free_block(struct bucket *buck); struct bucket *get_bucket(struct bucket *head, size_t size); void *get_data_begin(struct bucket *biquette); void *get_page_begin(void *ptr); -void bucket_append(struct bucket **head, struct bucket *elt); +void *get_block(struct bucket* biquette, int block_number); +void bucket_list_append(struct bucket **head, struct bucket *elt); +void bucket_list_remove(struct bucket **head, struct bucket *elt); #endif // ! HELPERS_H diff --git a/malloc/src/malloc.c b/malloc/src/malloc.c index 3f19f56..dfa093e 100644 --- a/malloc/src/malloc.c +++ b/malloc/src/malloc.c @@ -1,5 +1,7 @@ #include +#include +#include "helpers/allocate.h" #include "helpers/helpers.h" struct bucket *head = NULL; @@ -14,14 +16,13 @@ __attribute__((visibility("default"))) void *malloc(size_t size) while (buck != NULL) { // Find adequate block - void *block = find_free_block(buck); - if (block != NULL) - return block; + int block_number = find_free_block(buck); + if (block_number != -1) + return get_block(buck, block_number); else { // No free space -> loop buck = get_bucket(buck->next, size); - continue; } } @@ -34,14 +35,38 @@ __attribute__((visibility("default"))) void free(void *ptr) { if (ptr == NULL) return; + free_block(ptr, &head); } __attribute__((visibility("default"))) void *realloc(void *ptr, size_t size) { + if (size == 0) + return NULL; + if (ptr == NULL) + return malloc(size); + + struct bucket *header = get_page_begin(ptr); + if (header == NULL) + return NULL; // Shouldn't get here + + if (header->block_size >= size) + { + return ptr; + } + else + { + void *new_ptr = malloc(size); + memcpy(new_ptr, ptr, header->block_size); + free(ptr); + return new_ptr; + } + return NULL; } __attribute__((visibility("default"))) void *calloc(size_t nmemb, size_t size) { - return NULL; + char *res = malloc(nmemb * size); + memset(res, 0, nmemb * size); + return res; }