diff --git a/inc/malloc.h b/inc/malloc.h index 2bf08ee..6113771 100644 --- a/inc/malloc.h +++ b/inc/malloc.h @@ -40,9 +40,9 @@ typedef struct s_zones { extern pthread_mutex_t g_malloc_mutex; extern t_zones g_zones; -void *ft_malloc(size_t size); -void ft_free(void *ptr); -void *ft_realloc(void *ptr, size_t size); +void *malloc(size_t size); +void free(void *ptr); +void *realloc(void *ptr, size_t size); void show_alloc_mem(void); void show_alloc_mem_ex(void); @@ -51,5 +51,12 @@ void show_alloc_sizes(void); void init_tiny_zones(void); void init_small_zones(void); +size_t ft_strlen(const char *str); +void ft_putstr(char *str); +void ft_putnbr(size_t nbr); +void ft_putaddr(size_t nbr); +void ft_putchar(char c); +void ft_printf(const char *str, ...); + #endif diff --git a/main.c b/main.c index 1a52ae1..49cb951 100644 --- a/main.c +++ b/main.c @@ -3,38 +3,32 @@ int main(int argc, char **argv) { srand(argv[1][0]+argv[1][1]+argv[1][2]); - int **arr = (int **)ft_malloc(atoi(argv[2]) * sizeof(int *)); + int **arr = (int **)malloc(atoi(argv[2]) * sizeof(int *)); size_t size; for (int i = 0; i < atoi(argv[2]); i++) { size = (rand() & 0x7ff) | 0xf00000; - arr[i] = (int *)ft_malloc(size * sizeof(int)); - printf ("arr %d addr: %p arr size: %zu\n", i, arr[i], size); - //ft_free(arr); - } - ft_free(arr[3]); - ft_free(arr[5]); - ft_free(arr[1]); - ft_free(arr[6]); - ft_free(arr[2]); - ft_free(arr[4]); - ft_free(arr[0]); - ft_free(arr[7]); -// for (int i = 0; i < atoi(argv[2]); i++) { -// ft_free(arr[i]); -// } - printf("second round\n"); - for (int i = 0; i < atoi(argv[2]); i++) { - size = (rand() & 0x7ff) | 0xf00000; - arr[i] = (int *)ft_malloc(size * sizeof(int)); - printf ("arr %d addr: %p arr size: %zu\n", i, arr[i], size); - //ft_free(arr); + arr[i] = (int *)malloc(size * sizeof(int)); + ft_printf ("arr %d addr: %p arr size: %d\n", i, arr[i], size); + //free(arr); } for (int i = 0; i < atoi(argv[2]); i++) { - ft_free(arr[i]); + free(arr[i]); } - printf("free arr"); - ft_free(arr); + ft_printf("second round\n"); + for (int i = 0; i < atoi(argv[2]); i++) { + size = (rand() & 0x7ff);// | 0xf00000; + arr[i] = (int *)malloc(size * sizeof(int)); + ft_printf ("arr %d addr: %p arr size: %d\n", i, arr[i], size); + //free(arr); + } + for (int i = 0; i < atoi(argv[2]); i++) { + free(arr[i]); + } + ft_printf("free arr"); + free(arr); show_alloc_sizes(); + show_alloc_mem(); + ft_printf("%d\n", 42); return 0; } diff --git a/src/free.c b/src/free.c index eafcb31..da01f26 100644 --- a/src/free.c +++ b/src/free.c @@ -1,17 +1,29 @@ #include "malloc.h" -void ft_free(void *ptr) { +void free(void *ptr) { + write(1, "free\n", 5); pthread_mutex_lock(&g_malloc_mutex); + write(1, "free\n", 5); + if (ptr == NULL) { + ft_printf("free null\n"); + pthread_mutex_unlock(&g_malloc_mutex); + return; + } t_block *block = (t_block *)((char *)ptr - sizeof(t_block)); + write(1, "free\n", 5); if (block->size < g_zones.small_block_max_size) { + write(1, "rree\n", 5); block->free = 1; } else { + write(1, "1\n", 2); t_block *curr = g_zones.large_blocks; if (curr == NULL) { + write(1, "E\n", 2); pthread_mutex_unlock(&g_malloc_mutex); return; } if ((char *)curr + sizeof(t_block) == (char *)ptr) { + write(1, "2\n", 2); g_zones.large_blocks = curr->next; munmap((char *)ptr - sizeof(t_block) - (16 - sizeof(t_block) % 16), curr->size + sizeof(t_block) + (16 - sizeof(t_block) % 16)); pthread_mutex_unlock(&g_malloc_mutex); @@ -20,10 +32,12 @@ void ft_free(void *ptr) { while ((char *)curr->next + sizeof(t_block) != (char *)ptr) { curr = curr->next; if (curr == NULL) { + write(1, "e\n", 2); pthread_mutex_unlock(&g_malloc_mutex); return; } } + write(1, "3\n", 2); t_block *to_free = curr->next; curr->next = curr->next->next; munmap((char *)ptr - sizeof(t_block) - (16 - sizeof(t_block) % 16), to_free->size + sizeof(t_block) + (16 - sizeof(t_block) % 16)); diff --git a/src/init.c b/src/init.c index a02e130..5663b17 100644 --- a/src/init.c +++ b/src/init.c @@ -1,6 +1,6 @@ #include "malloc.h" -pthread_mutex_t g_malloc_mutex; +pthread_mutex_t g_malloc_mutex = PTHREAD_MUTEX_INITIALIZER; t_zones g_zones; void init_tiny_zones(void) { diff --git a/src/libft.c b/src/libft.c new file mode 100644 index 0000000..ecc8ac5 --- /dev/null +++ b/src/libft.c @@ -0,0 +1,73 @@ +#include "malloc.h" + +size_t ft_strlen(const char *str) { + size_t i = 0; + while (str[i]) { + i++; + } + return i; +} + +void ft_putstr(char *str) { + write(1, str, ft_strlen(str)); +} + +void ft_putnbr(size_t nbr) { + size_t tool = 10; + while (nbr > tool) { + tool *= 10; + } + tool /= 10; + while (tool >= 1) { + ft_putchar('0' + (nbr / tool) % 10); + tool /= 10; + } +} + +void ft_putaddr(size_t nbr) { + write(1, "0x", 2); + size_t tool = 16; + while (nbr > tool) { + tool *= 16; + } + while (tool >= 1) { + size_t digit = (nbr / tool) % 16; + if (digit < 10) { + ft_putchar('0' + digit); + } else { + ft_putchar('A' + digit - 10); + } + tool /= 16; + } +} + +void ft_putchar(char c) { + write(1, &c, 1); +} + +void ft_printf(const char *str, ...) { + va_list args; + va_start(args, str); + size_t len = ft_strlen(str); + for (size_t i = 0; i < len; i++) { + if (str[i] != '%') { + ft_putchar(str[i]); + } else if (i + 1 < len) { + char flag = str[i + 1]; + if (flag == 'd') { + ft_putnbr(va_arg(args, size_t)); + } else if (flag == 'p') { + ft_putaddr(va_arg(args, size_t)); + } else if (flag == 's') { + ft_putstr(va_arg(args, char *)); + } else { + write(1, "ft_printf format error 1\n", 25); + return; + } + i++; + } else { + write(1, "ft_printf format error 2\n", 25); + return; + } + } +} diff --git a/src/malloc.c b/src/malloc.c index b630b80..704f753 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -22,16 +22,16 @@ void *malloc_tiny(size_t size) { } zone->head = (t_block *)addr; curr = zone->head; - /*printf("addr of g_zones.tiny_zones : %p\n" + ft_printf("addr of g_zones.tiny_zones : %p\n" "addr of zone : %p\n" "addr of *head %p\n" - "sizeof tzone : %zu\n" - "size of tblock %zu\n", + "sizeof tzone : %d\n" + "size of tblock %d\n", g_zones.tiny_zones, zone, curr, sizeof(t_zone), - sizeof(t_block));*/ + sizeof(t_block)); curr->size = size; curr->free = 0; curr->next = NULL; @@ -62,6 +62,7 @@ void *malloc_tiny(size_t size) { zone = zone->next; } } + ft_printf("ITS A BIG MISTAKE IF IT EVER GOES THERE WHILE TRYING TO ALLOCATE A TINY BLOCK THAT WOULD BE A HUGE BUMMER AND WOULD MAKE THE HEADLINES OF INTERNATIONAL NEWS FOR A WEEK\n"); return NULL; } @@ -87,16 +88,16 @@ void *malloc_small(size_t size) { } zone->head = (t_block *)addr; curr = zone->head; - /*printf("addr of g_zones.small_zones : %p\n" + ft_printf("addr of g_zones.small_zones : %p\n" "addr of zone : %p\n" "addr of *head %p\n" - "sizeof tzone : %zu\n" - "size of tblock %zu\n", + "sizeof tzone : %d\n" + "size of tblock %d\n", g_zones.small_zones, zone, curr, sizeof(t_zone), - sizeof(t_block));*/ + sizeof(t_block)); curr->size = size; curr->free = 0; curr->next = NULL; @@ -127,6 +128,7 @@ void *malloc_small(size_t size) { zone = zone->next; } } + ft_printf("ITS A BIG MISTAKE IF IT EVER GOES THERE WHILE TRYING TO ALLOCATE A SMALL BLOCK THAT WOULD BE A HUGE BUMMER AND WOULD MAKE THE HEADLINES OF INTERNATIONAL NEWS FOR A WEEK\n"); return NULL; } @@ -153,14 +155,18 @@ void *malloc_large(size_t size) { return (void *)((char *)curr + sizeof(t_block)); } -void *ft_malloc(size_t size) { +void *malloc(size_t size) { pthread_mutex_lock(&g_malloc_mutex); + ft_printf("malloc %d\n", size); void *ptr = NULL; if (size < g_zones.tiny_block_max_size) { + write(1, "malloc tiny\n", 12); ptr = malloc_tiny(size); } else if (size < g_zones.small_block_max_size) { + write(1, "malloc small\n", 13); ptr = malloc_small(size); } else { + write(1, "malloc large\n", 13); ptr = malloc_large(size); } pthread_mutex_unlock(&g_malloc_mutex); diff --git a/src/realloc.c b/src/realloc.c index 825ba2c..0fd3cad 100644 --- a/src/realloc.c +++ b/src/realloc.c @@ -1,10 +1,87 @@ #include "malloc.h" +void ft_memcpy(char *dst, char *src, size_t size) { + write(1, "m\n", 2); + for (size_t i = 0; i < size; i++) { + dst[i] = src[i]; + } +} + void *realloc(void *ptr, size_t size) { + if (!ptr) { + return malloc(size); + } + write(1, "realloc\n", 8); + show_alloc_mem(); + ft_printf("realloc %p %d\n", ptr, size); pthread_mutex_lock(&g_malloc_mutex); - write(1, "1337\n", 5); - (void)size; - (void)ptr; + t_block *block = (t_block *)((char *)ptr - sizeof(t_block)); + if (block->size < g_zones.tiny_block_max_size) { + if (size >= g_zones.tiny_block_max_size) { + ft_printf("good\n"); + ft_printf("good\n"); + ft_printf("good\n"); + pthread_mutex_unlock(&g_malloc_mutex); + char *new_ptr = malloc(size); + pthread_mutex_lock(&g_malloc_mutex); + ft_printf("good\n"); + ft_printf("new_maloc_done\n"); + ft_memcpy(new_ptr, ptr, block->size); + ft_printf("done\n"); + pthread_mutex_unlock(&g_malloc_mutex); + free(ptr); + pthread_mutex_lock(&g_malloc_mutex); + } else { + // todo tiny to tiny realloc + pthread_mutex_unlock(&g_malloc_mutex); + void *new_ptr = malloc(size); + pthread_mutex_lock(&g_malloc_mutex); + ft_memcpy(new_ptr, ptr, block->size); + pthread_mutex_unlock(&g_malloc_mutex); + free(ptr); + pthread_mutex_lock(&g_malloc_mutex); + } + } else if (block->size < g_zones.small_block_max_size) { + if (size < g_zones.tiny_block_max_size || size >= g_zones.small_block_max_size) { + pthread_mutex_unlock(&g_malloc_mutex); + void *new_ptr = malloc(size); + pthread_mutex_lock(&g_malloc_mutex); + ft_memcpy(new_ptr, ptr, block->size); + pthread_mutex_unlock(&g_malloc_mutex); + free(ptr); + pthread_mutex_lock(&g_malloc_mutex); + } else { + // todo small to small realloc + pthread_mutex_unlock(&g_malloc_mutex); + void *new_ptr = malloc(size); + pthread_mutex_lock(&g_malloc_mutex); + ft_memcpy(new_ptr, ptr, block->size); + pthread_mutex_unlock(&g_malloc_mutex); + free(ptr); + pthread_mutex_lock(&g_malloc_mutex); + } + } else { + if (size < g_zones.small_block_max_size) { + pthread_mutex_unlock(&g_malloc_mutex); + void *new_ptr = malloc(size); + pthread_mutex_lock(&g_malloc_mutex); + ft_memcpy(new_ptr, ptr, block->size); + pthread_mutex_unlock(&g_malloc_mutex); + free(ptr); + pthread_mutex_lock(&g_malloc_mutex); + } else { + // todo large to large realloc + pthread_mutex_unlock(&g_malloc_mutex); + void *new_ptr = malloc(size); + pthread_mutex_lock(&g_malloc_mutex); + ft_memcpy(new_ptr, ptr, block->size); + pthread_mutex_unlock(&g_malloc_mutex); + free(ptr); + pthread_mutex_lock(&g_malloc_mutex); + } + } + ft_printf("exiting\n"); + show_alloc_mem(); pthread_mutex_unlock(&g_malloc_mutex); return ptr; } diff --git a/src/utils.c b/src/utils.c index 105f57c..56d18e3 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,6 +1,48 @@ #include "malloc.h" +void show_alloc_mem_tiny(void) { + t_zone *curr_zone = g_zones.tiny_zones; + while (curr_zone) { + ft_printf("TINY : %p\n", curr_zone); + t_block *curr_block = curr_zone->head; + while (curr_block) { + if (curr_block->free == 0) { + ft_printf("%p - %p : %d bytes\n", (char *)curr_block + sizeof(t_block), (char *)curr_block + sizeof(t_block) + curr_block->size, curr_block->size); + } + curr_block = curr_block->next; + } + curr_zone = curr_zone->next; + } +} + +void show_alloc_mem_small(void) { + t_zone *curr_zone = g_zones.small_zones; + while (curr_zone) { + ft_printf("SMALL: %p\n", curr_zone); + t_block *curr_block = curr_zone->head; + while (curr_block) { + if (curr_block->free == 0) { + ft_printf("%p - %p : %d bytes\n", (char *)curr_block + sizeof(t_block), (char *)curr_block + sizeof(t_block) + curr_block->size, curr_block->size); + } + curr_block = curr_block->next; + } + curr_zone = curr_zone->next; + } +} + +void show_alloc_mem_large(void) { + t_block *curr_block = g_zones.large_blocks; + while (curr_block) { + ft_printf("LARGE: %p\n", (char *)curr_block - 8); + ft_printf("%p - %p : %d bytes\n", (char *)curr_block + sizeof(t_block), (char *)curr_block + sizeof(t_block) + curr_block->size, curr_block->size); + curr_block = curr_block->next; + } +} + void show_alloc_mem(void) { + show_alloc_mem_tiny(); + show_alloc_mem_small(); + show_alloc_mem_large(); } void show_alloc_mem_ex(void) { @@ -8,7 +50,7 @@ void show_alloc_mem_ex(void) { void show_alloc_sizes(void) { // TODO remove me (printf) - printf("PAGESIZE : %zu bytes\n", g_zones.pagesize); - printf("TINY ZONE MAX BLOCK SIZE: %zu bytes\n", g_zones.tiny_block_max_size); - printf("SMALL ZONE MAX BLOCK SIZE : %zu bytes\n", g_zones.small_block_max_size); + ft_printf("PAGESIZE : %d bytes\n", g_zones.pagesize); + ft_printf("TINY ZONE MAX BLOCK SIZE: %d bytes\n", g_zones.tiny_block_max_size); + ft_printf("SMALL ZONE MAX BLOCK SIZE : %d bytes\n", g_zones.small_block_max_size); }