diff --git a/malloc/Makefile b/malloc/Makefile index 6b16c91..65f356b 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -1,29 +1,18 @@ CC=gcc -CFLAGS=-std=c99 -pedantic -Werror -Wall -Wextra -Wvla -fvisibility=hidden -fPIC -CPPFLAGS= -D_DEFAULT_SOURCE -LDFLAGS= -shared -Wl,--no-undefined -LDLIBS= +CFLAGS= +LDFLAGS= -SRCS=src/malloc.c src/helpers/helpers.c src/helpers/allocate.c -OBJS=${SRCS:.c=.o} -TST_OBJS = tests/test.o +SRCS= +OBJS=${SRC:.c=.o} TARGET=libmalloc.so library: $(OBJS) - $(CC) -o $(TARGET) $^ $(LDFLAGS) + $(CC) -shared -o $(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) +debug: check: - dash tests/test-cmd.sh clean: - $(RM) $(OBJS) + $(RM) *.o $(RM) $(TARGET) diff --git a/malloc/src/helpers/allocate.c b/malloc/src/helpers/allocate.c deleted file mode 100644 index 350a38b..0000000 --- a/malloc/src/helpers/allocate.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "allocate.h" - -#include -#include - -#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); - 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) -{ - size_t page_alloc_size; - size_t block_alloc_size; - - if (min_alloc_size > PAGE_SIZE - sizeof(struct bucket)) - { - // Huge page - page_alloc_size = min_alloc_size + sizeof(struct bucket); - block_alloc_size = page_alloc_size; - } - else - { - // Regular page - page_alloc_size = PAGE_SIZE; - block_alloc_size = s2p(min_alloc_size); - } - - // Get page - void *page = mmap(NULL, page_alloc_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - - if (page == NULL) - return NULL; - - // Init bucket - struct bucket *header = page; - header->block_size = block_alloc_size; - header->alloc_blk_cnt = 0; - header->alloc_size = page_alloc_size; - 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); - - // 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 = get_block_number(header, ptr); - if (block_number == -1) - return; - - unsigned char byte_mask = 1 << ((block_number % 8)); - header->free_map[block_number / 8] &= ~byte_mask; - header->alloc_blk_cnt--; - - // Huge page - // free bucket if necessary - if (header->alloc_blk_cnt == 0) - { - bucket_list_remove(list, header); - munmap(header, header->alloc_size); - } -} diff --git a/malloc/src/helpers/allocate.h b/malloc/src/helpers/allocate.h deleted file mode 100644 index fdb723b..0000000 --- a/malloc/src/helpers/allocate.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef ALLOCATE_H -#define ALLOCATE_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); -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 deleted file mode 100644 index bde2907..0000000 --- a/malloc/src/helpers/helpers.c +++ /dev/null @@ -1,170 +0,0 @@ -#include "helpers.h" - -// 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 = MIN_BLOCK_SIZE; - while (n < s) - { - n <<= 1; - } - - return n; -} - -int find_free_block(struct bucket *buck) -{ - // 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]; - if (map_byte == 0xFF) // Skip if used - continue; - - 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; - } - } - - 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) - return NULL; - - char *data_begin = get_data_begin(biquette); - 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) - return -1; - - char *block_nul = block; - 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; -} - -// 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) - { - 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) -{ - void *maisqueltrucdemerde = biquette; - char *biquettas = maisqueltrucdemerde; - return biquettas + 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); - char *pointeur_alacon = NULL; - 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; - if (list_elt == NULL) - { - *head = elt; - return; - } - - while (list_elt->next != NULL) - { - list_elt = list_elt->next; - } - 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 = elt->next; - 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 deleted file mode 100644 index 8c64cfe..0000000 --- a/malloc/src/helpers/helpers.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef HELPERS_H -#define HELPERS_H - -// #define PAGE_SIZE sysconf(_SC_PAGE_SIZE) -#define PAGE_SIZE 4096 -#define MIN_BLOCK_SIZE 16 -#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_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 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) - -size_t s2p(size_t n); -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); -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); - -#endif // ! HELPERS_H diff --git a/malloc/src/malloc.c b/malloc/src/malloc.c index 535c23e..8b99ad9 100644 --- a/malloc/src/malloc.c +++ b/malloc/src/malloc.c @@ -1,82 +1,19 @@ #include -#include - -#include "helpers/allocate.h" -#include "helpers/helpers.h" - -struct bucket *head = NULL; __attribute__((visibility("default"))) void *malloc(size_t size) { - if (size == 0) - return NULL; - - // Find adequate bucket - struct bucket *buck = get_bucket(head, size); - while (buck != NULL) - { - // Find adequate block - int block_number = find_free_block(buck); - if (block_number != -1) - return allocate_block(buck, block_number); - else - { - // No free space -> loop - buck = get_bucket(buck->next, size); - } - } - - buck = create_bucket(size); - bucket_list_append(&head, buck); - int first_free_buche = find_free_block(buck); // De noel (pas la mienne) - return allocate_block(buck, first_free_buche); + return NULL; } __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); - if (new_ptr == NULL) - return NULL; - 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) { - // 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; + return NULL; } diff --git a/malloc/tests/test-cmd.sh b/malloc/tests/test-cmd.sh deleted file mode 100755 index 4ff60e6..0000000 --- a/malloc/tests/test-cmd.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/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 --help 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 diff --git a/malloc/tests/test.c b/malloc/tests/test.c deleted file mode 100644 index 51a4f94..0000000 --- a/malloc/tests/test.c +++ /dev/null @@ -1,25 +0,0 @@ -// #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); -}