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..bde2907 100644 --- a/malloc/src/helpers/helpers.c +++ b/malloc/src/helpers/helpers.c @@ -32,19 +32,32 @@ 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 +81,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 - biquette_cherie - sizeof(struct bucket)) - / biquette->block_size; + 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 @@ -93,7 +115,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 +154,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