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 0000000..9e8ed5c Binary files /dev/null and b/malloc/library differ diff --git a/malloc/src/helpers/allocate.c b/malloc/src/helpers/allocate.c index 9c8739f..9bfef58 100644 --- a/malloc/src/helpers/allocate.c +++ b/malloc/src/helpers/allocate.c @@ -4,16 +4,17 @@ #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) - 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); +}