From 231b283e0def5b1a9a906e7ded9cfc613c9185c9 Mon Sep 17 00:00:00 2001 From: tomoron Date: Mon, 2 Dec 2024 20:18:59 +0100 Subject: [PATCH] add realloc, rename bloc to chunk, start thinking of chunk sizes --- srcs/free.c | 50 +++++++++++++++++---------- srcs/includes/malloc.h | 22 ++++++------ srcs/malloc.c | 70 +++++++++++++++++++------------------- srcs/realloc.c | 77 ++++++++++++++++++++++++++++++++++++++++++ srcs/show_alloc_mem.c | 14 ++++---- 5 files changed, 163 insertions(+), 70 deletions(-) create mode 100644 srcs/realloc.c diff --git a/srcs/free.c b/srcs/free.c index 9453c15..9c0f1ae 100644 --- a/srcs/free.c +++ b/srcs/free.c @@ -6,14 +6,20 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/11/30 18:46:07 by tomoron #+# #+# */ -/* Updated: 2024/12/01 18:47:12 by tomoron ### ########.fr */ +/* Updated: 2024/12/02 19:54:00 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "includes/malloc.h" -t_mem_bloc *get_alloc_bloc(t_alloc *alloc, t_mem_bloc *first, size_t size) +t_mem_chunk *get_alloc_chunk(t_alloc *alloc, t_mem_chunk *first,int is_small) { + size_t size; + + if(is_small) + size = SMALL_CHUNK_SIZE; + else + size = TINY_CHUNK_SIZE; while(first) { if((t_ul)alloc >= (t_ul)first && ((t_ul)alloc - (t_ul)(first + 1)) <= size) @@ -27,6 +33,7 @@ int get_prev_alloc(t_alloc **alloc, t_alloc **res, t_alloc *cur) { t_alloc *prev; + *res = 0; if(cur == *alloc) return(1); prev = 0; @@ -49,27 +56,32 @@ int get_prev_alloc(t_alloc **alloc, t_alloc **res, t_alloc *cur) return(0); } -int free_prealloc(t_alloc *alloc, t_mem_bloc **main_bloc, size_t size) +int free_prealloc(t_alloc *alloc, t_mem_chunk **main_chunk, int is_small) { - t_mem_bloc *bloc; + t_mem_chunk *chunk; t_alloc *prev; + size_t size; prev = 0; - bloc = get_alloc_bloc(alloc, *main_bloc, size); - if(!bloc) + chunk = get_alloc_chunk(alloc, *main_chunk, is_small); + if(!chunk) return(0); - if(!get_prev_alloc(&alloc, &prev, bloc->first)) + if(!get_prev_alloc(&alloc, &prev, chunk->first)) return(1); - bloc->space_left -= alloc->size + sizeof(t_alloc); - if(bloc->first == alloc) - bloc->first = alloc->next; + chunk->space_left -= alloc->size + sizeof(t_alloc); + if(chunk->first == alloc) + chunk->first = alloc->next; else if(prev) prev->next = alloc->next; - if(!bloc->first) + if(!chunk->first) { - if(*main_bloc == bloc) - *main_bloc = bloc->next; - munmap(bloc, size); + if(*main_chunk == chunk) + *main_chunk = chunk->next; + if(is_small) + size = SMALL_CHUNK_SIZE; + else + size = TINY_CHUNK_SIZE; + munmap(chunk, size); } return(1); } @@ -87,14 +99,16 @@ void free_large(t_alloc *alloc) munmap(alloc, alloc->size + sizeof(t_alloc)); } -void ft_free(void *ptr) +void free(void *ptr) { t_alloc *alloc; - alloc = (t_alloc *)ptr - 1; - if(free_prealloc(alloc, &g_allocs.tiny, TINY_BLOC_SIZE)) + if(!ptr) return ; - if(free_prealloc(alloc, &g_allocs.small, SMALL_BLOC_SIZE)) + alloc = (t_alloc *)ptr - 1; + if(free_prealloc(alloc, &g_allocs.tiny, 0)) + return ; + if(free_prealloc(alloc, &g_allocs.small, 1)) return ; free_large(alloc); } diff --git a/srcs/includes/malloc.h b/srcs/includes/malloc.h index 45f9f35..7604ac0 100644 --- a/srcs/includes/malloc.h +++ b/srcs/includes/malloc.h @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/11/26 16:38:01 by tomoron #+# #+# */ -/* Updated: 2024/12/01 03:08:41 by tomoron ### ########.fr */ +/* Updated: 2024/12/02 20:18:33 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -20,30 +20,31 @@ # define PAGE_SIZE sysconf(_SC_PAGESIZE) -# define TINY_BLOC_SIZE (PAGE_SIZE * 4) -# define SMALL_BLOC_SIZE 524288 # define TINY_MALLOC 1024 # define SMALL_MALLOC 4096 +# define TINY_CHUNK_SIZE (((16 + TINY_MALLOC) * 100) + 32) +# define SMALL_CHUNK_SIZE 524288 + typedef struct s_alloc { size_t size; //8 struct s_alloc *next; //8 } t_alloc; //size 16 -typedef struct s_mem_bloc +typedef struct s_mem_chunk { size_t space_left; //8 - struct s_mem_bloc *next; //8 + struct s_mem_chunk *next; //8 t_alloc *first; //8 char padding[8]; -} t_mem_bloc; //size 32 +} t_mem_chunk; //size 32 typedef struct s_allocations { - t_mem_bloc *tiny; - t_mem_bloc *small; + t_mem_chunk *tiny; + t_mem_chunk *small; t_alloc *large; } t_allocations; @@ -51,8 +52,9 @@ typedef unsigned long t_ul; extern t_allocations g_allocs; -void *ft_malloc(size_t size); +void *malloc(size_t size); void show_alloc_mem(); -void ft_free(void *ptr); +void free(void *ptr); +void *realloc(void *ptr, size_t size); #endif diff --git a/srcs/malloc.c b/srcs/malloc.c index e1d56c5..4794ae9 100644 --- a/srcs/malloc.c +++ b/srcs/malloc.c @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/11/23 17:19:59 by tomoron #+# #+# */ -/* Updated: 2024/12/01 19:21:27 by tomoron ### ########.fr */ +/* Updated: 2024/12/02 19:54:00 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,28 +19,28 @@ t_allocations g_allocs; void *get_memory(size_t size, int no_write) { - t_mem_bloc *bloc; + t_mem_chunk *chunk; - bloc = mmap(0, size, PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, + chunk = mmap(0, size, PROT_WRITE | PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); - if (bloc == MAP_FAILED) + if (chunk == MAP_FAILED) return (0); if(no_write) - return(bloc); - bloc->space_left = size - sizeof(t_mem_bloc); - bloc->next = 0; - return (bloc); + return(chunk); + chunk->space_left = size - sizeof(t_mem_chunk); + chunk->next = 0; + return (chunk); } t_alloc *reserve_addr(t_alloc *addr, size_t size, t_alloc *prev, - t_mem_bloc *bloc) + t_mem_chunk *chunk) { t_alloc *tmp; if ((t_ul)addr % 16) addr = (t_alloc *)((char *)addr + (16 - ((t_ul)addr % 16))); addr->size = size; - bloc->space_left -= (size + sizeof(t_alloc)); + chunk->space_left -= (size + sizeof(t_alloc)); if (prev) { tmp = prev->next; @@ -52,20 +52,20 @@ t_alloc *reserve_addr(t_alloc *addr, size_t size, t_alloc *prev, return (addr + 1); } -t_alloc *get_suitable_addr_in_bloc(t_mem_bloc *bloc, size_t size) +t_alloc *get_suitable_addr_in_chunk(t_mem_chunk *chunk, size_t size) { t_alloc *tmp; size_t space_left; size_t free_space; - tmp = bloc->first; - space_left = bloc->space_left; - if((t_ul)bloc->first - (t_ul)(bloc + 1) >= size + sizeof(t_alloc)) + tmp = chunk->first; + space_left = chunk->space_left; + if((t_ul)chunk->first - (t_ul)(chunk + 1) >= size + sizeof(t_alloc)) { - tmp = bloc->first; - bloc->first = reserve_addr((void *)(bloc + 1), size, 0, bloc) - 1; - bloc->first->next = tmp; - return(bloc->first + 1); + tmp = chunk->first; + chunk->first = reserve_addr((void *)(chunk + 1), size, 0, chunk) - 1; + chunk->first->next = tmp; + return(chunk->first + 1); } while (tmp->next) { @@ -73,64 +73,64 @@ t_alloc *get_suitable_addr_in_bloc(t_mem_bloc *bloc, size_t size) if (free_space >= size + sizeof(t_alloc)) return (reserve_addr( (void *)((char *)tmp + tmp->size + sizeof(t_alloc)), - size, tmp, bloc)); + size, tmp, chunk)); space_left -= free_space; tmp = tmp->next; } if (space_left >= size + sizeof(t_alloc)) return (reserve_addr( (t_alloc *)((char *)tmp + tmp->size + sizeof(t_alloc)), - size, tmp, bloc)); + size, tmp, chunk)); return (0); } -t_mem_bloc *create_new_bloc(int is_small, t_mem_bloc **bloc, t_mem_bloc *prev) +t_mem_chunk *create_new_chunk(int is_small, t_mem_chunk **chunk, t_mem_chunk *prev) { - t_mem_bloc *new; + t_mem_chunk *new; size_t mmap_size; if (is_small) - mmap_size = SMALL_BLOC_SIZE; + mmap_size = SMALL_CHUNK_SIZE; else - mmap_size = TINY_BLOC_SIZE; + mmap_size = TINY_CHUNK_SIZE; new = get_memory(mmap_size, 0); if (!new) return (0); new->first = (t_alloc *)(new + 1); if (prev) prev->next = new; - if (!*bloc) - *bloc = new; + if (!*chunk) + *chunk = new; return (new); } -void *pre_allocated(size_t size, t_mem_bloc **bloc, int is_small) +void *pre_allocated(size_t size, t_mem_chunk **chunk, int is_small) { - t_mem_bloc *tmp; - t_mem_bloc *prev; + t_mem_chunk *tmp; + t_mem_chunk *prev; t_alloc *res; - tmp = *bloc; - prev = *bloc; + tmp = *chunk; + prev = *chunk; res = 0; while (tmp) { if (tmp->space_left >= size) { - res = get_suitable_addr_in_bloc(tmp, size); + res = get_suitable_addr_in_chunk(tmp, size); if (res) return (res); } prev = tmp; tmp = tmp->next; } - tmp = create_new_bloc(is_small, bloc, prev); + tmp = create_new_chunk(is_small, chunk, prev); if (!tmp) return (0); - return (reserve_addr((void *)tmp + sizeof(t_mem_bloc), size, 0, tmp)); + return (reserve_addr((void *)tmp + sizeof(t_mem_chunk), size, 0, tmp)); } -void *ft_malloc(size_t size) +void *malloc(size_t size) { t_alloc *new; diff --git a/srcs/realloc.c b/srcs/realloc.c new file mode 100644 index 0000000..6117eb7 --- /dev/null +++ b/srcs/realloc.c @@ -0,0 +1,77 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* realloc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tomoron +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/12/02 14:41:22 by tomoron #+# #+# */ +/* Updated: 2024/12/02 19:54:00 by tomoron ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "includes/malloc.h" +t_mem_chunk *get_alloc_chunk(t_alloc *alloc, t_mem_chunk *first, size_t size); +int get_prev_alloc(t_alloc **alloc, t_alloc **res, t_alloc *cur); + +void *realloc_recreate(t_alloc *alloc, size_t size) +{ + void *new; + + new = malloc(size); + if(alloc->size < size) + size = alloc->size; + ft_memcpy(new, alloc + 1, size); + free(alloc + 1); + return(new); +} + +void *realloc_prealloc(t_alloc *alloc, t_mem_chunk *chunk, int is_small, size_t size) +{ + t_alloc *prev; + + chunk = get_alloc_chunk(alloc, chunk, is_small); + if(!chunk) + return(0); + if(!get_prev_alloc(&alloc, &prev, chunk->first)) + return(0); + if(alloc->size >= size) + { + chunk->space_left += alloc->size - size; + alloc->size = size; + return(alloc + 1); + } + if((size > (size_t)TINY_CHUNK_SIZE && is_small == 0) + || (size > SMALL_CHUNK_SIZE && is_small == 1) + || (t_ul)(alloc->next) - (t_ul)(alloc + 1) < size) + return(realloc_recreate(alloc, size)); + chunk->space_left -= size - alloc->size; + alloc->size = size; + return(alloc + 1); +} + +void *realloc_large(t_alloc *alloc, size_t size) +{ + t_alloc *prev; + + if(!get_prev_alloc(&alloc, &prev, g_allocs.large)) + return(0); + return(realloc_recreate(alloc, size)); +} + +void *realloc(void *ptr, size_t size) +{ + t_alloc *alloc; + + if(!ptr) + return(malloc(size)); + alloc = (t_alloc *)ptr - 1; + ptr = realloc_prealloc(alloc, g_allocs.tiny, 0, size); + if(ptr) + return(ptr); + ptr = realloc_prealloc(alloc, g_allocs.tiny, 1, size); + if(ptr) + return(ptr); + return(realloc_large(alloc, size)); + +} diff --git a/srcs/show_alloc_mem.c b/srcs/show_alloc_mem.c index 26ed6bc..5b335f2 100644 --- a/srcs/show_alloc_mem.c +++ b/srcs/show_alloc_mem.c @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/11/30 12:19:34 by tomoron #+# #+# */ -/* Updated: 2024/12/01 03:05:08 by tomoron ### ########.fr */ +/* Updated: 2024/12/02 15:24:45 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -46,19 +46,19 @@ size_t show_allocs(t_alloc *alloc) return(nb_bytes); } -size_t show_pre_allocated(char *type, t_mem_bloc *bloc) +size_t show_pre_allocated(char *type, t_mem_chunk *chunk) { size_t nb_bytes; nb_bytes = 0; - while(bloc) + while(chunk) { write(1, type, ft_strlen(type)); write(1, " : 0x", 5); - put_ulnbr_base((t_ul)bloc, "0123456789ABCDEF"); + put_ulnbr_base((t_ul)chunk, "0123456789ABCDEF"); write(1, "\n", 1); - nb_bytes += show_allocs(bloc->first); - bloc = bloc->next; + nb_bytes += show_allocs(chunk->first); + chunk = chunk->next; } return(nb_bytes); } @@ -98,5 +98,5 @@ void show_alloc_mem() total += show_large(); write(1, "Total : ", 8); put_ulnbr_base(total, "0123456789"); - write(1, " bytes\n", 6); + write(1, " bytes\n", 7); }