From 7629201717eb056823924eda00e291857026191f Mon Sep 17 00:00:00 2001 From: Guillem George Date: Tue, 4 Nov 2025 19:13:31 +0100 Subject: [PATCH 01/10] ' --- malloc/Makefile | 10 ++++++---- malloc/src/helpers/helpers.c | 4 ++++ malloc/src/helpers/helpers.h | 8 ++++++++ malloc/src/malloc.c | 3 ++- 4 files changed, 20 insertions(+), 5 deletions(-) create mode 100644 malloc/src/helpers/helpers.c create mode 100644 malloc/src/helpers/helpers.h diff --git a/malloc/Makefile b/malloc/Makefile index 65f356b..6334b0d 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -1,15 +1,17 @@ CC=gcc -CFLAGS= -LDFLAGS= +CFLAGS=-std=c99 -pedantic -Werror -Wall -Wextra -Wvla -fvisibility=hidden -fPIC +CPPFLAGS=D_DEFAULT_SOURCE +LDFLAGS= -shared -Wl --no-undefined SRCS= OBJS=${SRC:.c=.o} TARGET=libmalloc.so library: $(OBJS) - $(CC) -shared -o $(TARGET) $^ + $(CC) -o $(TARGET) $^ -debug: +debug: $(OBJS) $(TST_OBJS) + $(CC) -o $(TST_TARGET) $^ check: diff --git a/malloc/src/helpers/helpers.c b/malloc/src/helpers/helpers.c new file mode 100644 index 0000000..bba1bc1 --- /dev/null +++ b/malloc/src/helpers/helpers.c @@ -0,0 +1,4 @@ +#include "helpers.h" + +size_t get_next_2power(size_t n) +{} diff --git a/malloc/src/helpers/helpers.h b/malloc/src/helpers/helpers.h new file mode 100644 index 0000000..4d5b403 --- /dev/null +++ b/malloc/src/helpers/helpers.h @@ -0,0 +1,8 @@ +#ifndef HELPERS_H +#define HELPERS_H + +#include + +size_t get_next_2power(size_t n); + +#endif // ! HELPERS_H diff --git a/malloc/src/malloc.c b/malloc/src/malloc.c index 8b99ad9..26e8ab1 100644 --- a/malloc/src/malloc.c +++ b/malloc/src/malloc.c @@ -2,7 +2,8 @@ __attribute__((visibility("default"))) void *malloc(size_t size) { - return NULL; + if (size == 0) + return NULL; } __attribute__((visibility("default"))) void free(void *ptr) From ed8a843d3d34c3a7d7158521163032637b28d7d7 Mon Sep 17 00:00:00 2001 From: Guillem George Date: Wed, 5 Nov 2025 21:22:34 +0100 Subject: [PATCH 02/10] ' --- malloc/src/helpers/helpers.c | 61 ++++++++++++++++++++++++++++++++++-- malloc/src/helpers/helpers.h | 10 ++++++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/malloc/src/helpers/helpers.c b/malloc/src/helpers/helpers.c index bba1bc1..52db459 100644 --- a/malloc/src/helpers/helpers.c +++ b/malloc/src/helpers/helpers.c @@ -1,4 +1,61 @@ #include "helpers.h" -size_t get_next_2power(size_t n) -{} +#include + +// Returns the smallest power of 2 greater or equal to s +size_t s2p(size_t s) +{ + // Trick I found on the internet but I don't completely understand it + // Quite amazing + // n--; // 1101 1101 --> 1101 1100 + // n |= n >> 1; // 1101 1100 | 0110 1110 = 1111 1110 + // n |= n >> 2; // 1111 1110 | 0011 1111 = 1111 1111 + // n |= n >> 4; // ... + // n |= n >> 8; + // n |= n >> 16; // 1111 1111 | 1111 1111 = 1111 1111 + // n++; // 1111 1111 --> 1 0000 0000 + + // There is also an x86 assembly instruction to do that in a single cycle: + // lzcnt + // Yeah... This one is definetely wild intel + // Now since asm{} is prohibited in the coding style it won't be useful + // Or maybe there is a builtin to do that ? + // (found __builtin_clzll but not sure of what it does) + + // So here's the good old way + size_t n = 1; + while (n < s) + { + n <<= 1; + } + + return n; +} + +void *find_free_block(struct bucket *buck) +{ + unsigned maplength = buck->block_size / 8; + // for each block + for (unsigned i = 0; i < maplength; i++) + { + unsigned char map_byte = buck->free_list[i]; + unsigned char bit = 1; + // Test byte + for (unsigned j = 0; j < 8; j <<= 1) + { + if (map_byte & bit) // Test if free + return buck->page + (buck->block_size * (i * 8 + j)); + + bit <<= 1; + } + } + + return NULL; +} + +struct bucket *create_bucket(size_t min_alloc_size) +{ + size_t alloc_size = s2p(min_alloc_size); + void *page = + mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, -1, 0); +} diff --git a/malloc/src/helpers/helpers.h b/malloc/src/helpers/helpers.h index 4d5b403..51477f5 100644 --- a/malloc/src/helpers/helpers.h +++ b/malloc/src/helpers/helpers.h @@ -3,6 +3,16 @@ #include +struct bucket +{ + unsigned block_size; + unsigned char free_list[64]; // 4096 / MIN_BLOCK_SIZE / + // sizeof(unsigned char) (in bits) + char *page; +}; + size_t get_next_2power(size_t n); +void *find_free_block(struct bucket *buck); +struct bucket *create_bucket(size_t min_alloc_size); #endif // ! HELPERS_H From 5aba0ff0c34fcd9a8fb91f78ee3587a23e6f8a9f Mon Sep 17 00:00:00 2001 From: Guillem George Date: Thu, 6 Nov 2025 19:56:55 +0100 Subject: [PATCH 03/10] backup --- malloc/src/helpers/helpers.c | 25 +++++++++++++++++++++++++ malloc/src/helpers/helpers.h | 16 ++++++++++++++-- malloc/src/malloc.c | 11 +++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/malloc/src/helpers/helpers.c b/malloc/src/helpers/helpers.c index 52db459..928234e 100644 --- a/malloc/src/helpers/helpers.c +++ b/malloc/src/helpers/helpers.c @@ -1,5 +1,6 @@ #include "helpers.h" +#include #include // Returns the smallest power of 2 greater or equal to s @@ -55,7 +56,31 @@ void *find_free_block(struct bucket *buck) struct bucket *create_bucket(size_t min_alloc_size) { + // 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) + return NULL; + + // Init bucket + struct bucket *header = page; + header->page = page + sizeof(struct bucket); + header->block_size = alloc_size; + memset(header->free_list, 0, FREE_LIST_SIZE); + + return header; +} + +struct bucket *get_free_bucket(struct bucket *head, size_t size) +{ + while (head != NULL) + { + if (head->block_size >= size) + return head; + } + + return NULL; } diff --git a/malloc/src/helpers/helpers.h b/malloc/src/helpers/helpers.h index 51477f5..c6c622c 100644 --- a/malloc/src/helpers/helpers.h +++ b/malloc/src/helpers/helpers.h @@ -1,18 +1,30 @@ #ifndef HELPERS_H #define HELPERS_H +// #define PAGE_SIZE (size_t) 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) + #include +// Header +// Contains all informations about the concerned bucket struct bucket { unsigned block_size; - unsigned char free_list[64]; // 4096 / MIN_BLOCK_SIZE / - // sizeof(unsigned char) (in bits) + unsigned char free_list[FREE_LIST_SIZE]; // 4096 / MIN_BLOCK_SIZE / + // sizeof(unsigned char) char *page; + + struct bucket *next; + + size_t checksum; }; size_t get_next_2power(size_t n); void *find_free_block(struct bucket *buck); struct bucket *create_bucket(size_t min_alloc_size); +struct bucket *get_free_bucket(struct bucket *head, size_t size); #endif // ! HELPERS_H diff --git a/malloc/src/malloc.c b/malloc/src/malloc.c index 26e8ab1..4419fdb 100644 --- a/malloc/src/malloc.c +++ b/malloc/src/malloc.c @@ -1,9 +1,20 @@ #include +#include "helpers/helpers.h" + +struct bucket *head = NULL; + __attribute__((visibility("default"))) void *malloc(size_t size) { if (size == 0) return NULL; + + struct bucket *buck = get_free_bucket(head, size); + if (buck == NULL) + { + buck = create_bucket(size); + return ...; + } } __attribute__((visibility("default"))) void free(void *ptr) From 06fac933c21d0cec60b977846b4bdf94c84e13c7 Mon Sep 17 00:00:00 2001 From: Guillem George Date: Thu, 6 Nov 2025 22:14:56 +0100 Subject: [PATCH 04/10] tuez-moi --- malloc/src/helpers/helpers.c | 36 +++++++++++++++++++++++++++++++++--- malloc/src/helpers/helpers.h | 11 ++++++----- malloc/src/malloc.c | 26 +++++++++++++++++++++----- 3 files changed, 60 insertions(+), 13 deletions(-) diff --git a/malloc/src/helpers/helpers.c b/malloc/src/helpers/helpers.c index 928234e..df0e7fa 100644 --- a/malloc/src/helpers/helpers.c +++ b/malloc/src/helpers/helpers.c @@ -45,7 +45,7 @@ void *find_free_block(struct bucket *buck) for (unsigned j = 0; j < 8; j <<= 1) { if (map_byte & bit) // Test if free - return buck->page + (buck->block_size * (i * 8 + j)); + return get_data_begin(buck) + (buck->block_size * (i * 8 + j)); bit <<= 1; } @@ -67,14 +67,15 @@ struct bucket *create_bucket(size_t min_alloc_size) // Init bucket struct bucket *header = page; - header->page = page + sizeof(struct bucket); header->block_size = alloc_size; memset(header->free_list, 0, FREE_LIST_SIZE); return header; } -struct bucket *get_free_bucket(struct bucket *head, size_t size) +// Gets a bucket with at least a block_size of size +// Returns NULL if nothing was found +struct bucket *get_bucket(struct bucket *head, size_t size) { while (head != NULL) { @@ -84,3 +85,32 @@ struct bucket *get_free_bucket(struct bucket *head, size_t size) return NULL; } + +void *get_data_begin(struct bucket *biquette) +{ + // TODO alignment + return biquette + sizeof(struct bucket); +} + +void *get_page_begin(void *ptr) +{ + size_t quelenfer = ((size_t)ptr) & ~(PAGE_SIZE - 1); + char *pointeur_alacon = NULL; + return pointeur_alacon + quelenfer; +} + +void bucket_append(struct bucket **head, struct bucket *elt) +{ + struct bucket *list_elt = *head; + if (list_elt == NULL) + { + *head = elt; + return; + } + + while (list_elt->next != NULL) + { + list_elt = list_elt->next; + } + list_elt->next = elt; +} diff --git a/malloc/src/helpers/helpers.h b/malloc/src/helpers/helpers.h index c6c622c..217f7e9 100644 --- a/malloc/src/helpers/helpers.h +++ b/malloc/src/helpers/helpers.h @@ -14,17 +14,18 @@ struct bucket { unsigned block_size; unsigned char free_list[FREE_LIST_SIZE]; // 4096 / MIN_BLOCK_SIZE / - // sizeof(unsigned char) - char *page; - + // sizeof(unsigned char) struct bucket *next; size_t checksum; }; -size_t get_next_2power(size_t n); +size_t s2p(size_t n); void *find_free_block(struct bucket *buck); struct bucket *create_bucket(size_t min_alloc_size); -struct bucket *get_free_bucket(struct bucket *head, size_t size); +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); #endif // ! HELPERS_H diff --git a/malloc/src/malloc.c b/malloc/src/malloc.c index 4419fdb..3f19f56 100644 --- a/malloc/src/malloc.c +++ b/malloc/src/malloc.c @@ -9,16 +9,32 @@ __attribute__((visibility("default"))) void *malloc(size_t size) if (size == 0) return NULL; - struct bucket *buck = get_free_bucket(head, size); - if (buck == NULL) + // Find adequate bucket + struct bucket *buck = get_bucket(head, size); + while (buck != NULL) { - buck = create_bucket(size); - return ...; + // Find adequate block + void *block = find_free_block(buck); + if (block != NULL) + return block; + else + { + // No free space -> loop + buck = get_bucket(buck->next, size); + continue; + } } + + buck = create_bucket(size); + bucket_append(&head, buck); + return get_data_begin(buck); } __attribute__((visibility("default"))) void free(void *ptr) -{} +{ + if (ptr == NULL) + return; +} __attribute__((visibility("default"))) void *realloc(void *ptr, size_t size) { From b4f942f678dc63a433ef2f2b774b8429a0d54e71 Mon Sep 17 00:00:00 2001 From: Guillem George Date: Fri, 7 Nov 2025 20:29:21 +0100 Subject: [PATCH 05/10] 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; } From a531db5e3a10ac9de1fac43710708475e9a3da3d Mon Sep 17 00:00:00 2001 From: Guillem George Date: Fri, 7 Nov 2025 23:29:21 +0100 Subject: [PATCH 06/10] backup --- malloc/Makefile | 19 ++++++++++++++----- malloc/library | Bin 0 -> 17152 bytes malloc/src/helpers/allocate.c | 34 +++++++++++++++++++++++++++------- malloc/src/helpers/allocate.h | 4 ++-- malloc/src/helpers/helpers.c | 12 +++++++++--- malloc/src/helpers/helpers.h | 12 ++++++++---- malloc/src/malloc.c | 6 +++--- malloc/tests/test-cmd.sh | 3 +++ malloc/tests/test.c | 25 +++++++++++++++++++++++++ 9 files changed, 91 insertions(+), 24 deletions(-) create mode 100755 malloc/library create mode 100755 malloc/tests/test-cmd.sh create mode 100644 malloc/tests/test.c diff --git a/malloc/Makefile b/malloc/Makefile index 2ee592b..6b16c91 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -1,20 +1,29 @@ CC=gcc CFLAGS=-std=c99 -pedantic -Werror -Wall -Wextra -Wvla -fvisibility=hidden -fPIC CPPFLAGS= -D_DEFAULT_SOURCE -LDFLAGS= -shared -Wl --no-undefined +LDFLAGS= -shared -Wl,--no-undefined +LDLIBS= SRCS=src/malloc.c src/helpers/helpers.c src/helpers/allocate.c OBJS=${SRCS:.c=.o} +TST_OBJS = tests/test.o TARGET=libmalloc.so library: $(OBJS) - $(CC) -o $(TARGET) $^ + $(CC) -o $(TARGET) $^ $(LDFLAGS) -debug: $(OBJS) $(TST_OBJS) - $(CC) -o $(TST_TARGET) $^ +debug: CFLAGS += -g +debug: $(OBJS) + $(CC) -o $(TARGET) $^ $(LDFLAGS) + +# test: LDLIBS += -lcriterion +test: CFLAGS = -g -L. -lmalloc -fPIC -fvisibility=hidden +test: library $(TST_OBJS) + $(CC) -o $(TST_TARGET) $^ $(LDLIBS) check: + dash tests/test-cmd.sh clean: - $(RM) *.o + $(RM) $(OBJS) $(RM) $(TARGET) diff --git a/malloc/library b/malloc/library new file mode 100755 index 0000000000000000000000000000000000000000..9e8ed5c580f8adb3c2cbed4c385678806ead2765 GIT binary patch literal 17152 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 #include "helpers.h" - +// c'est dangereux de pas s'i3lock +// coucou 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); + unsigned char byte_mask = 1 << (8 - 1 - (block_number % 8)); biquette->alloc_blk_cnt++; - biquette->free_map[block_number / 8] &= byte_mask; + biquette->free_map[block_number / 8] |= byte_mask; // Compute block address return get_block(biquette, block_number); @@ -31,8 +32,8 @@ struct bucket *create_bucket(size_t min_alloc_size) alloc_size = s2p(min_alloc_size); // Get page - void *page = - mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, -1, 0); + void *page = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (page == NULL) return NULL; @@ -41,6 +42,7 @@ struct bucket *create_bucket(size_t min_alloc_size) struct bucket *header = page; header->block_size = alloc_size; header->alloc_blk_cnt = 0; + header->alloc_size = alloc_size; memset(header->free_map, 0, FREE_LIST_SIZE); return header; @@ -51,8 +53,26 @@ void free_block(void *ptr, struct bucket **list) // Compute header location and block number struct bucket *header = get_page_begin(ptr); + // Verify that header belongs to list + struct bucket *elt = *list; + int found = 0; + while (elt != NULL) + { + if (elt == header) + { + found = 1; + break; + } + elt = elt->next; + } + if (!found) + return; + // free in map and update size - int block_number; // ... + int block_number = get_block_number(header, ptr); + if (block_number == -1) + return; + unsigned char byte_mask = 1 << ((block_number % 8) - 1); header->free_map[block_number / 8] &= ~byte_mask; @@ -65,6 +85,6 @@ void free_block(void *ptr, struct bucket **list) if (header->alloc_blk_cnt == 0) { bucket_list_remove(list, header); - munmap(ptr, 1); + munmap(header, header->alloc_size); } } diff --git a/malloc/src/helpers/allocate.h b/malloc/src/helpers/allocate.h index 3e91a0e..fdb723b 100644 --- a/malloc/src/helpers/allocate.h +++ b/malloc/src/helpers/allocate.h @@ -1,10 +1,10 @@ #ifndef ALLOCATE_H #define ALLOCATE_H -#include "helpers.h" - #include +#include "helpers.h" + 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); diff --git a/malloc/src/helpers/helpers.c b/malloc/src/helpers/helpers.c index 8091eda..8b37f4a 100644 --- a/malloc/src/helpers/helpers.c +++ b/malloc/src/helpers/helpers.c @@ -21,7 +21,7 @@ size_t s2p(size_t s) // (found __builtin_clzll but not sure of what it does) // So here's the good old way - size_t n = 1; + size_t n = MIN_BLOCK_SIZE; while (n < s) { n <<= 1; @@ -41,7 +41,7 @@ int find_free_block(struct bucket *buck) // Test byte for (unsigned j = 0; j < 8; j <<= 1) { - if (map_byte & bit) // Test if free + if (map_byte ^ bit) // Test if free return i * 8 + j; bit <<= 1; @@ -51,6 +51,7 @@ int find_free_block(struct bucket *buck) return -1; } +// Computes the block address based on its position in the freemap void *get_block(struct bucket *biquette, int block_number) { if (block_number == -1) @@ -60,6 +61,7 @@ void *get_block(struct bucket *biquette, int block_number) return data_begin + (biquette->block_size * (block_number)); } +// Gets block position in the freemap based on its address int get_block_number(struct bucket *biquette, void *block) { if (block == NULL || biquette == NULL) @@ -81,17 +83,20 @@ struct bucket *get_bucket(struct bucket *head, size_t size) { if (head->block_size >= size) return head; + + head = head->next; } return NULL; } +// Computes the buckets first block address void *get_data_begin(struct bucket *biquette) { - // TODO alignment return biquette + sizeof(struct bucket); } +// Computes the beginning address of the page containing ptr void *get_page_begin(void *ptr) { size_t quelenfer = ((size_t)ptr) & ~(PAGE_SIZE - 1); @@ -99,6 +104,7 @@ void *get_page_begin(void *ptr) return pointeur_alacon + quelenfer; } +// Appends a bucket address to the list pointed by head void bucket_list_append(struct bucket **head, struct bucket *elt) { struct bucket *list_elt = *head; diff --git a/malloc/src/helpers/helpers.h b/malloc/src/helpers/helpers.h index ec8bd0b..8c64cfe 100644 --- a/malloc/src/helpers/helpers.h +++ b/malloc/src/helpers/helpers.h @@ -3,7 +3,7 @@ // #define PAGE_SIZE sysconf(_SC_PAGE_SIZE) #define PAGE_SIZE 4096 -#define MIN_BLOCK_SIZE 8 +#define MIN_BLOCK_SIZE 16 #define FREE_LIST_SIZE PAGE_SIZE / MIN_BLOCK_SIZE / sizeof(unsigned char) #include @@ -13,13 +13,16 @@ struct bucket { unsigned block_size; - unsigned char free_map[FREE_LIST_SIZE]; // Keeps track of allocations + 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; + size_t alloc_size; + + unsigned short space1; // + unsigned int space2; // -> Both are used to align data on 16 bytes }; #define BUCKET_SIZE PAGE_SIZE - sizeof(struct bucket) @@ -29,7 +32,8 @@ 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 *get_block(struct bucket* biquette, int block_number); +void *get_block(struct bucket *biquette, int block_number); +int get_block_number(struct bucket *biquette, void *block); void bucket_list_append(struct bucket **head, struct bucket *elt); void bucket_list_remove(struct bucket **head, struct bucket *elt); diff --git a/malloc/src/malloc.c b/malloc/src/malloc.c index dfa093e..961d899 100644 --- a/malloc/src/malloc.c +++ b/malloc/src/malloc.c @@ -18,7 +18,7 @@ __attribute__((visibility("default"))) void *malloc(size_t size) // Find adequate block int block_number = find_free_block(buck); if (block_number != -1) - return get_block(buck, block_number); + return allocate_block(buck, block_number); else { // No free space -> loop @@ -27,8 +27,8 @@ __attribute__((visibility("default"))) void *malloc(size_t size) } buck = create_bucket(size); - bucket_append(&head, buck); - return get_data_begin(buck); + bucket_list_append(&head, buck); + return allocate_block(buck, 1); } __attribute__((visibility("default"))) void free(void *ptr) diff --git a/malloc/tests/test-cmd.sh b/malloc/tests/test-cmd.sh new file mode 100755 index 0000000..e561d85 --- /dev/null +++ b/malloc/tests/test-cmd.sh @@ -0,0 +1,3 @@ +#!/bi/sh + +echo Hello world! diff --git a/malloc/tests/test.c b/malloc/tests/test.c new file mode 100644 index 0000000..51a4f94 --- /dev/null +++ b/malloc/tests/test.c @@ -0,0 +1,25 @@ +// #include +// #include + +// TestSuite(Main); + +// Test(Main, test1) +// { +// int *i = malloc(16); +// cr_assert(i != NULL); +// } + +#include + +int main(void) +{ + int *test = malloc(8); + void *tes2 = malloc(8); + void *tes3 = malloc(32); + void *tes4 = malloc(64); + void *tes5 = malloc(128); + void *tes6 = malloc(256); + void *tes7 = malloc(512); + void *tes8 = malloc(4096); + void *tes9 = malloc(95956); +} From 56636b54c4895296ffb6e50ab5e08ee77a03f81a Mon Sep 17 00:00:00 2001 From: Guillem George Date: Fri, 7 Nov 2025 23:30:27 +0100 Subject: [PATCH 07/10] backup --- malloc/library | Bin 17152 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 malloc/library diff --git a/malloc/library b/malloc/library deleted file mode 100755 index 9e8ed5c580f8adb3c2cbed4c385678806ead2765..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17152 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 Date: Fri, 7 Nov 2025 23:38:51 +0100 Subject: [PATCH 08/10] nul --- malloc/tests/test-cmd.sh | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/malloc/tests/test-cmd.sh b/malloc/tests/test-cmd.sh index e561d85..e633a4c 100755 --- a/malloc/tests/test-cmd.sh +++ b/malloc/tests/test-cmd.sh @@ -1,3 +1,24 @@ #!/bi/sh +RED='\033[0;31m' +NC='\033[0m' # No color + echo Hello world! + +check() +{ + if [ $? -ne 0 ]; then + echo $RED ERROR $NC + fi +} +LD_PRELOAD=./libmalloc.so ls 1> /dev/null +check +LD_PRELOAD=./libmalloc.so ip a 1> /dev/null +check +LD_PRELOAD=./libmalloc.so grep 1> /dev/null +check +LD_PRELOAD=./libmalloc.so find 1> /dev/null +check +LD_PRELOAD=./libmalloc.so tree 1> /dev/null +check +LD_PRELOAD=./libmalloc.so git status 1> /dev/null From 4f8a0bb720e1d6668ba9cb7618e29b840019edee Mon Sep 17 00:00:00 2001 From: "Gu://em_" Date: Thu, 18 Dec 2025 18:06:44 +0100 Subject: [PATCH 09/10] malloc moi le fion --- malloc/src/helpers/allocate.c | 30 ++++++++++++--------- malloc/src/helpers/helpers.c | 51 ++++++++++++++++++++++++----------- malloc/src/malloc.c | 14 ++++++++-- malloc/tests/test-cmd.sh | 2 +- 4 files changed, 66 insertions(+), 31 deletions(-) diff --git a/malloc/src/helpers/allocate.c b/malloc/src/helpers/allocate.c index 9bfef58..350a38b 100644 --- a/malloc/src/helpers/allocate.c +++ b/malloc/src/helpers/allocate.c @@ -12,7 +12,7 @@ void *allocate_block(struct bucket *biquette, int block_number) return NULL; // Update header - unsigned char byte_mask = 1 << (8 - 1 - (block_number % 8)); + unsigned char byte_mask = 1 << (block_number % 8); biquette->alloc_blk_cnt++; biquette->free_map[block_number / 8] |= byte_mask; @@ -22,17 +22,24 @@ void *allocate_block(struct bucket *biquette, int block_number) struct bucket *create_bucket(size_t min_alloc_size) { - // Round up - size_t alloc_size; + size_t page_alloc_size; + size_t block_alloc_size; + if (min_alloc_size > PAGE_SIZE - sizeof(struct bucket)) + { // Huge page - alloc_size = min_alloc_size; + page_alloc_size = min_alloc_size + sizeof(struct bucket); + block_alloc_size = page_alloc_size; + } else + { // Regular page - alloc_size = s2p(min_alloc_size); + page_alloc_size = PAGE_SIZE; + block_alloc_size = s2p(min_alloc_size); + } // Get page - void *page = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, + void *page = mmap(NULL, page_alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); if (page == NULL) @@ -40,9 +47,9 @@ struct bucket *create_bucket(size_t min_alloc_size) // Init bucket struct bucket *header = page; - header->block_size = alloc_size; + header->block_size = block_alloc_size; header->alloc_blk_cnt = 0; - header->alloc_size = alloc_size; + header->alloc_size = page_alloc_size; memset(header->free_map, 0, FREE_LIST_SIZE); return header; @@ -73,14 +80,11 @@ void free_block(void *ptr, struct bucket **list) if (block_number == -1) return; - unsigned char byte_mask = 1 << ((block_number % 8) - 1); + unsigned char byte_mask = 1 << ((block_number % 8)); header->free_map[block_number / 8] &= ~byte_mask; + header->alloc_blk_cnt--; // 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) { diff --git a/malloc/src/helpers/helpers.c b/malloc/src/helpers/helpers.c index 8b37f4a..04ef038 100644 --- a/malloc/src/helpers/helpers.c +++ b/malloc/src/helpers/helpers.c @@ -32,19 +32,29 @@ size_t s2p(size_t s) int find_free_block(struct bucket *buck) { - unsigned maplength = PAGE_SIZE / buck->block_size / 8; - // for each block + // Huge pages + if (buck->block_size > BUCKET_SIZE) + { + // Check block 0 + if (!(buck->free_map[0] & (1 << 0))) + return 0; + return -1; + } + + size_t num_blocks_in_page = (PAGE_SIZE - sizeof(struct bucket)) / buck->block_size; + size_t maplength = (num_blocks_in_page + 7) / 8; // +7 for ceiling division (oui c'est moche mais ça marche) + + // Foreach byte for (unsigned i = 0; i < maplength; 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 i * 8 + j; + if (map_byte == 0xFF) // Skip if used + continue; - bit <<= 1; + for (unsigned j = 0; j < 8; j++) + { + if ((i * 8 + j) < num_blocks_in_page && !(map_byte & (1 << j))) // Check if free + return i * 8 + j; } } @@ -68,11 +78,20 @@ int get_block_number(struct bucket *biquette, void *block) return -1; char *block_nul = block; - void *biquetteounette = biquette; - char *biquette_cherie = biquetteounette; + char* bibiche = get_data_begin(biquette); // Célèbre bar Capcinois, venez à l'occasion + + return (block_nul - bibiche) / biquette->block_size; + + // Au revoir mes belles + // Vous manquerez à papa + // (mais fallait marcher, là ça marche pas) + + // void *biquetteounette = biquette; + // char *biquette_cherie = biquetteounette; + + // return (block_nul - biquette_cherie - sizeof(struct bucket)) + // / biquette->block_size; - return (block_nul - biquette_cherie - sizeof(struct bucket)) - / biquette->block_size; } // Gets a bucket with at least a block_size of size @@ -93,7 +112,9 @@ struct bucket *get_bucket(struct bucket *head, size_t size) // Computes the buckets first block address void *get_data_begin(struct bucket *biquette) { - return biquette + sizeof(struct bucket); + void* maisqueltrucdemerde = biquette; + char* biquettas = maisqueltrucdemerde; + return biquettas + sizeof(struct bucket); } // Computes the beginning address of the page containing ptr @@ -130,7 +151,7 @@ void bucket_list_remove(struct bucket **head, struct bucket *elt) if (*head == elt) { - *head = NULL; + *head = elt->next; return; } diff --git a/malloc/src/malloc.c b/malloc/src/malloc.c index 961d899..535c23e 100644 --- a/malloc/src/malloc.c +++ b/malloc/src/malloc.c @@ -28,7 +28,8 @@ __attribute__((visibility("default"))) void *malloc(size_t size) buck = create_bucket(size); bucket_list_append(&head, buck); - return allocate_block(buck, 1); + int first_free_buche = find_free_block(buck); // De noel (pas la mienne) + return allocate_block(buck, first_free_buche); } __attribute__((visibility("default"))) void free(void *ptr) @@ -56,6 +57,8 @@ __attribute__((visibility("default"))) void *realloc(void *ptr, size_t size) else { void *new_ptr = malloc(size); + if (new_ptr == NULL) + return NULL; memcpy(new_ptr, ptr, header->block_size); free(ptr); return new_ptr; @@ -66,7 +69,14 @@ __attribute__((visibility("default"))) void *realloc(void *ptr, size_t size) __attribute__((visibility("default"))) void *calloc(size_t nmemb, size_t size) { - char *res = malloc(nmemb * size); + // Check overflow + size_t c; + if (__builtin_mul_overflow(nmemb, size, &c)) + return NULL; + + char *res = malloc(c); + if (res == NULL) + return NULL; memset(res, 0, nmemb * size); return res; } diff --git a/malloc/tests/test-cmd.sh b/malloc/tests/test-cmd.sh index e633a4c..4ff60e6 100755 --- a/malloc/tests/test-cmd.sh +++ b/malloc/tests/test-cmd.sh @@ -15,7 +15,7 @@ LD_PRELOAD=./libmalloc.so ls 1> /dev/null check LD_PRELOAD=./libmalloc.so ip a 1> /dev/null check -LD_PRELOAD=./libmalloc.so grep 1> /dev/null +LD_PRELOAD=./libmalloc.so grep --help 1> /dev/null check LD_PRELOAD=./libmalloc.so find 1> /dev/null check From a09cf2de17a909ac39b9c2fa33ef546669bd63a9 Mon Sep 17 00:00:00 2001 From: "Gu://em_" Date: Fri, 19 Dec 2025 19:02:50 +0100 Subject: [PATCH 10/10] masterclass le dementor --- malloc/src/helpers/helpers.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/malloc/src/helpers/helpers.c b/malloc/src/helpers/helpers.c index 04ef038..bde2907 100644 --- a/malloc/src/helpers/helpers.c +++ b/malloc/src/helpers/helpers.c @@ -41,8 +41,10 @@ int find_free_block(struct bucket *buck) return -1; } - size_t num_blocks_in_page = (PAGE_SIZE - sizeof(struct bucket)) / buck->block_size; - size_t maplength = (num_blocks_in_page + 7) / 8; // +7 for ceiling division (oui c'est moche mais ça marche) + size_t num_blocks_in_page = + (PAGE_SIZE - sizeof(struct bucket)) / buck->block_size; + size_t maplength = (num_blocks_in_page + 7) + / 8; // +7 for ceiling division (oui c'est moche mais ça marche) // Foreach byte for (unsigned i = 0; i < maplength; i++) @@ -52,8 +54,9 @@ int find_free_block(struct bucket *buck) continue; for (unsigned j = 0; j < 8; j++) - { - if ((i * 8 + j) < num_blocks_in_page && !(map_byte & (1 << j))) // Check if free + { + if ((i * 8 + j) < num_blocks_in_page + && !(map_byte & (1 << j))) // Check if free return i * 8 + j; } } @@ -78,7 +81,8 @@ int get_block_number(struct bucket *biquette, void *block) return -1; char *block_nul = block; - char* bibiche = get_data_begin(biquette); // Célèbre bar Capcinois, venez à l'occasion + char *bibiche = + get_data_begin(biquette); // Célèbre bar Capcinois, venez à l'occasion return (block_nul - bibiche) / biquette->block_size; @@ -91,7 +95,6 @@ int get_block_number(struct bucket *biquette, void *block) // return (block_nul - biquette_cherie - sizeof(struct bucket)) // / biquette->block_size; - } // Gets a bucket with at least a block_size of size @@ -112,8 +115,8 @@ struct bucket *get_bucket(struct bucket *head, size_t size) // Computes the buckets first block address void *get_data_begin(struct bucket *biquette) { - void* maisqueltrucdemerde = biquette; - char* biquettas = maisqueltrucdemerde; + void *maisqueltrucdemerde = biquette; + char *biquettas = maisqueltrucdemerde; return biquettas + sizeof(struct bucket); }