├── Makefile ├── README ├── calloc.c ├── free.c ├── fusion.c ├── get_heap.c ├── malloc.c ├── malloc.h ├── rbtree.h ├── rbtree ├── flip_color.c ├── insert.c ├── insert_utils.c ├── remove.c ├── remove_utils.c └── rotate.c ├── realloc.c └── show_alloc_mem.c /Makefile: -------------------------------------------------------------------------------- 1 | ## 2 | ## Makefile for epitech in /home/chapui_s/travaux/malloc_ok/Makefile 3 | ## 4 | ## Made by chapui_s 5 | ## Login 6 | ## 7 | ## Started on Sun Feb 15 19:58:32 2015 chapui_s 8 | ## Last update Sat Feb 21 19:33:09 2015 chapui_s 9 | ## 10 | 11 | ifndef HOSTTYPE 12 | HOSTTYPE = $(shell uname -i) 13 | endif 14 | 15 | NAME = libmy_malloc_$(HOSTTYPE).so 16 | 17 | SRC = malloc.c \ 18 | free.c \ 19 | calloc.c \ 20 | realloc.c \ 21 | fusion.c \ 22 | get_heap.c \ 23 | show_alloc_mem.c \ 24 | rbtree/insert.c \ 25 | rbtree/rotate.c \ 26 | rbtree/insert_utils.c \ 27 | rbtree/remove.c \ 28 | rbtree/flip_color.c \ 29 | rbtree/remove_utils.c 30 | 31 | OBJ = $(SRC:.c=.o) 32 | 33 | CFLAGS += -O3 -Wall -Wextra -fPIC -shared -I . 34 | 35 | CC = gcc 36 | 37 | RM = rm -f 38 | 39 | $(NAME): $(OBJ) 40 | $(CC) $(CFLAGS) $(OBJ) -o $(NAME) 41 | @echo -e "\033[0;032m[$(NAME)] Compiled\033[0;0m" 42 | ln -fs $(NAME) libmy_malloc.so 43 | @echo -e "\033[0;032m[libmy_malloc.so] Link created\033[0;0m" 44 | 45 | all: $(NAME) 46 | 47 | clean: 48 | @echo -e "\033[0;031m[clean] " | tr -d '\n' 49 | rm -f $(OBJ) 50 | @echo -e "\033[0;0m" | tr -d '\n' 51 | 52 | fclean: clean 53 | @echo -e "\033[0;031m[fclean] " | tr -d '\n' 54 | rm -f $(NAME) 55 | $(RM) libmy_malloc.so 56 | @echo -e "\033[0;0m" | tr -d '\n' 57 | 58 | re: fclean all 59 | 60 | .PHONY: all clean fclean re 61 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Malloc 2 | ====== 3 | 4 | malloc(), free(), realloc() and calloc() implementation using a red-black tree. 5 | malloc() allocates memory from the heap using sbrk(), according to the memory page size. 6 | The default alignment is 8 and 16 bytes on x86 and x86_64 systems, respectively. 7 | Mutexes are used to avoid corruption. 8 | 9 | Define BEST_FIT during compilation to use best-fit algorithm instead of first-fit algorithm (file malloc.c). 10 | 11 | Can be used with any programs but the ones using their own memory allocator. 12 | With some systems and some programs, glibc is used, you have to define in the environment G_SLICE=always-malloc. 13 | 14 | Example 15 | ======= 16 | $ G_SLICE=always-malloc LD_PRELOAD=./libmy_malloc.so gimp | firefox | gdb | ... 17 | -------------------------------------------------------------------------------- /calloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** calloc.c for epitech in /home/chapui_s/travaux/malloc/ 3 | ** 4 | ** Made by chapui_s 5 | ** Login 6 | ** 7 | ** Started on Mon Feb 2 15:52:40 2015 chapui_s 8 | ** Last update Sun Feb 15 19:31:43 2015 chapui_s 9 | */ 10 | 11 | #include "malloc.h" 12 | 13 | extern t_malloc g_info; 14 | 15 | void *calloc(size_t nmemb, size_t size) 16 | { 17 | void *ptr; 18 | 19 | if (nmemb == 0 || size == 0) 20 | return ((void*)0); 21 | if ((ptr = malloc(size * nmemb)) == (void*)0) 22 | return ((void*)0); 23 | pthread_mutex_lock(&(g_info.mutex)); 24 | bzero(ptr, ALIGN_BYTES(size * nmemb)); 25 | pthread_mutex_unlock(&(g_info.mutex)); 26 | return (ptr); 27 | } 28 | -------------------------------------------------------------------------------- /free.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** free.c for epitech in /home/chapui_s/travaux/malloc/ 3 | ** 4 | ** Made by chapui_s 5 | ** Login 6 | ** 7 | ** Started on Sun Feb 15 19:50:03 2015 chapui_s 8 | ** Last update Sun Feb 15 23:03:29 2015 chapui_s 9 | */ 10 | 11 | #include "malloc.h" 12 | 13 | extern t_malloc g_info; 14 | 15 | static void invalid_pointer(void *ptr) 16 | { 17 | printf("Error in '%s': free(): invalid pointer: %p\n", 18 | ((__progname) ? (__progname) : ("Unknow")), ptr); 19 | abort(); 20 | } 21 | 22 | static void double_free(void *ptr) 23 | { 24 | printf("Error in '%s': free(): double free: %p\n", 25 | ((__progname) ? (__progname) : ("Unknow")), ptr); 26 | abort(); 27 | } 28 | 29 | static inline t_metadata *try_fusion(t_metadata *node) 30 | { 31 | while (IS_FREE(node->prev)) 32 | { 33 | g_info.root_rbtree = remove_from_freed_list(g_info.root_rbtree, 34 | node->prev); 35 | node = fusion(node->prev, node); 36 | } 37 | while (IS_FREE(node->next)) 38 | { 39 | g_info.root_rbtree = remove_from_freed_list(g_info.root_rbtree, 40 | node->next); 41 | node = fusion(node, node->next); 42 | } 43 | return (node); 44 | } 45 | 46 | static inline void change_break(t_metadata *node) 47 | { 48 | size_t pages_to_remove; 49 | 50 | if (node->prev) 51 | { 52 | node->prev->next = (t_metadata*)0; 53 | g_info.last_node = node->prev; 54 | g_info.end_in_page = (void*)g_info.last_node + g_info.last_node->size; 55 | } 56 | else 57 | { 58 | g_info.end_in_page = g_info.last_node; 59 | g_info.last_node = (t_metadata*)0; 60 | } 61 | g_info.page_remaining += node->size; 62 | pages_to_remove = g_info.page_remaining / g_info.page_size; 63 | brk((sbrk(0) - (pages_to_remove * g_info.page_size))); 64 | g_info.page_remaining = g_info.page_remaining 65 | - (pages_to_remove * g_info.page_size); 66 | } 67 | 68 | void free(void *ptr) 69 | { 70 | t_metadata *node; 71 | 72 | if (!ptr) 73 | return ; 74 | pthread_mutex_lock(&(g_info.mutex)); 75 | node = GET_NODE(ptr); 76 | if (ptr < g_info.first_block || ptr > g_info.end_in_page || !IS_VALID(node)) 77 | invalid_pointer(ptr); 78 | if (node->free == YFREE) 79 | double_free(ptr); 80 | node = try_fusion(node); 81 | if (!node->next) 82 | change_break(node); 83 | else 84 | g_info.root_rbtree = insert_in_freed_list(g_info.root_rbtree, node); 85 | pthread_mutex_unlock(&(g_info.mutex)); 86 | } 87 | -------------------------------------------------------------------------------- /fusion.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** fusion.c for epitech in /home/chapui_s/travaux/malloc/ 3 | ** 4 | ** Made by chapui_s 5 | ** Login 6 | ** 7 | ** Started on Sun Feb 15 19:49:50 2015 chapui_s 8 | ** Last update Sun Feb 15 23:03:21 2015 chapui_s 9 | */ 10 | 11 | #include "malloc.h" 12 | 13 | extern t_malloc g_info; 14 | 15 | t_metadata *fusion(t_metadata *first, t_metadata *second) 16 | { 17 | first->size += second->size; 18 | first->next = second->next; 19 | if (first->next) 20 | first->next->prev = first; 21 | else 22 | g_info.last_node = first; 23 | return (first); 24 | } 25 | -------------------------------------------------------------------------------- /get_heap.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** get_heap.c for epitech in /home/chapui_s/travaux/malloc_ok/ 3 | ** 4 | ** Made by chapui_s 5 | ** Login 6 | ** 7 | ** Started on Sun Feb 15 19:52:25 2015 chapui_s 8 | ** Last update Sun Feb 15 22:06:22 2015 chapui_s 9 | */ 10 | 11 | #include "malloc.h" 12 | 13 | extern t_malloc g_info; 14 | 15 | static size_t get_new_page(size_t size) 16 | { 17 | size_t pages; 18 | 19 | pages = ((size / g_info.page_size) + 1) * g_info.page_size; 20 | if (!g_info.end_in_page) 21 | { 22 | if ((g_info.end_in_page = sbrk(0)) == (void*)-1) 23 | return ((size_t)-1); 24 | g_info.first_block = g_info.end_in_page; 25 | } 26 | if (sbrk(pages) == (void*)-1) 27 | { 28 | errno = ENOMEM; 29 | return ((size_t)-1); 30 | } 31 | return (pages); 32 | } 33 | 34 | static void *get_in_page(size_t size) 35 | { 36 | t_metadata *new; 37 | 38 | new = g_info.end_in_page; 39 | new->size = size; 40 | new->free = NFREE; 41 | new->next = (t_metadata*)0; 42 | new->prev = g_info.last_node; 43 | if (g_info.last_node) 44 | g_info.last_node->next = new; 45 | g_info.last_node = new; 46 | g_info.end_in_page = (void*)new + size; 47 | return (new); 48 | } 49 | 50 | void *get_heap(size_t size) 51 | { 52 | size_t tmp; 53 | 54 | if (g_info.page_remaining < size) 55 | { 56 | if ((tmp = get_new_page(size)) == (size_t)-1) 57 | return ((void*)0); 58 | g_info.page_remaining += tmp; 59 | } 60 | g_info.page_remaining -= size; 61 | return (get_in_page(size)); 62 | } 63 | -------------------------------------------------------------------------------- /malloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** malloc.c for epitech in /home/chapui_s/travaux/malloc/ 3 | ** 4 | ** Made by chapui_s 5 | ** Login 6 | ** 7 | ** Started on Mon Feb 2 15:52:40 2015 chapui_s 8 | ** Last update Sun Feb 15 23:30:22 2015 chapui_s 9 | */ 10 | 11 | #include "malloc.h" 12 | 13 | t_malloc g_info = { 14 | .root_rbtree = (t_rbnode*)0, 15 | .last_node = (t_metadata*)0, 16 | .end_in_page = (void*)0, 17 | .first_block = (void*)0, 18 | .page_size = 0, 19 | .mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER, 20 | .page_remaining = 0 21 | }; 22 | 23 | #ifdef FIND_BEST 24 | 25 | static inline t_rbnode *find_best(t_rbnode *node, size_t size) 26 | { 27 | t_rbnode *tmp; 28 | 29 | tmp = (t_rbnode*)0; 30 | while (node) 31 | { 32 | if (node->key >= size) 33 | { 34 | tmp = node; 35 | node = node->left; 36 | } 37 | else 38 | node = node->right; 39 | } 40 | return (tmp); 41 | } 42 | 43 | static t_metadata *search_freed_block(t_rbnode *node, size_t size) 44 | { 45 | t_metadata **tab; 46 | size_t size_tab; 47 | size_t i; 48 | t_rbnode *tmp; 49 | 50 | i = 0; 51 | tmp = find_best(node, size); 52 | if (tmp) 53 | { 54 | size_tab = tmp->size_tab; 55 | tab = tmp->tab_values; 56 | while (i < size_tab) 57 | { 58 | if (tab[i]) 59 | return (tab[i]); 60 | i += 1; 61 | } 62 | } 63 | return ((t_metadata*)0); 64 | } 65 | 66 | #else /* !FIND_BEST */ 67 | 68 | static t_metadata *search_freed_block(t_rbnode *node, size_t size) 69 | { 70 | t_metadata **tab; 71 | size_t size_tab; 72 | size_t i; 73 | 74 | i = 0; 75 | while (node) 76 | { 77 | if (node->key >= size) 78 | { 79 | size_tab = node->size_tab; 80 | tab = node->tab_values; 81 | while (i < size_tab) 82 | { 83 | if (tab[i]) 84 | return (tab[i]); 85 | i += 1; 86 | } 87 | } 88 | node = node->right; 89 | } 90 | return ((t_metadata*)0); 91 | } 92 | 93 | #endif /* !FIND_BEST */ 94 | 95 | static void *split_block(t_metadata *node, size_t size) 96 | { 97 | t_metadata *new; 98 | 99 | g_info.root_rbtree = remove_from_freed_list(g_info.root_rbtree, node); 100 | if (node->size > size + sizeof(size_t) 101 | && node->size - size > sizeof(t_rbnode) + SIZE_DEFAULT_BLOCK) 102 | { 103 | new = (void*)node + size; 104 | new->size = node->size - size; 105 | new->free = YFREE; 106 | new->prev = node; 107 | new->next = node->next; 108 | node->next = new; 109 | node->size = size; 110 | if (new->next) 111 | new->next->prev = new; 112 | g_info.root_rbtree = insert_in_freed_list(g_info.root_rbtree, new); 113 | } 114 | return (node); 115 | } 116 | 117 | void *malloc(size_t size) 118 | { 119 | t_metadata *tmp; 120 | void *ptr; 121 | 122 | pthread_mutex_lock(&(g_info.mutex)); 123 | if (size < SIZE_DEFAULT_BLOCK) 124 | size = SIZE_DEFAULT_BLOCK; 125 | size = ALIGN_BYTES(size) + META_SIZE; 126 | if (!g_info.page_size) 127 | g_info.page_size = getpagesize(); 128 | if ((tmp = search_freed_block(g_info.root_rbtree, size))) 129 | ptr = split_block(tmp, size); 130 | else 131 | ptr = get_heap(size); 132 | pthread_mutex_unlock(&(g_info.mutex)); 133 | return ((ptr) ? (GET_PAYLOAD(ptr)) : (0)); 134 | } 135 | -------------------------------------------------------------------------------- /malloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** malloc.h for epitech in /home/chapui_s/travaux/malloc_rbtree/malloc.h 3 | ** 4 | ** Made by chapui_s 5 | ** Login 6 | ** 7 | ** Started on Tue Jan 27 04:44:22 2015 chapui_s 8 | ** Last update Tue Feb 3 17:27:42 2015 chapui_s 9 | */ 10 | 11 | #ifndef MALLOC_H_ 12 | # define MALLOC_H_ 13 | 14 | # include 15 | # include 16 | # include "rbtree.h" 17 | 18 | #endif /* !MALLOC_H_ */ 19 | -------------------------------------------------------------------------------- /rbtree.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** rbtree.h for rbtree in /home/chapuis_s/rendu/rbtree 3 | ** 4 | ** Made by chapui_s 5 | ** Login 6 | ** 7 | ** Started on Mon Jan 26 19:41:38 2015 chapui_s 8 | ** Last update Sun Feb 15 23:17:13 2015 chapui_s 9 | */ 10 | 11 | #ifndef RBTREE_H_ 12 | # define RBTREE_H_ 13 | 14 | # include 15 | # include 16 | # include 17 | # include 18 | # include 19 | # include 20 | # include 21 | 22 | typedef enum rbcolor 23 | { 24 | BLACK = 0, 25 | RED = 1 26 | } t_rbcolor; 27 | 28 | typedef struct s_metadata 29 | { 30 | size_t size; 31 | size_t free; 32 | struct s_metadata *next; 33 | struct s_metadata *prev; 34 | } t_metadata; 35 | 36 | typedef size_t t_key; 37 | typedef t_metadata t_value; 38 | 39 | typedef struct s_rbnode 40 | { 41 | size_t size; 42 | size_t free; 43 | t_metadata *next; 44 | t_metadata *prev; 45 | t_key key; 46 | t_value **tab_values; 47 | size_t size_tab; 48 | size_t nb_activ; 49 | t_rbcolor color; 50 | struct s_rbnode *left; 51 | struct s_rbnode *right; 52 | } t_rbnode; 53 | 54 | typedef struct s_malloc 55 | { 56 | t_rbnode *root_rbtree; 57 | t_metadata *last_node; 58 | void *end_in_page; 59 | void *first_block; 60 | int page_size; 61 | pthread_mutex_t mutex; 62 | size_t page_remaining; 63 | } t_malloc; 64 | 65 | # ifdef __x86_64__ 66 | # define YFREE 0xDEADBEEF5EBA571E 67 | # define NFREE 0x5EBA571EDEADBEEF 68 | # define ALIGN_BYTES(x) ((((x - 1) >> 4) << 4) + 16) 69 | # else /* !__x86_64__ */ 70 | # define YFREE 0x5EBA571E 71 | # define NFREE 0xDEADBEEF 72 | # define ALIGN_BYTES(x) ((((x - 1) >> 3) << 3) + 8) 73 | # endif /* !__x86_64__ */ 74 | 75 | # define SIZE_TAB_VALUES (256) 76 | # define META_SIZE ALIGN_BYTES((sizeof(t_metadata))) 77 | # define GET_PAYLOAD(x) ((void*)((size_t)x + META_SIZE)) 78 | # define GET_NODE(x) ((void*)((size_t)x - META_SIZE)) 79 | # define SIZE_DEFAULT_BLOCK (32) 80 | # define IS_VALID(x) (((t_metadata*)x)->free == YFREE \ 81 | || ((t_metadata*)x)->free == NFREE) 82 | # define IS_FREE(x) ((x) ? (((t_metadata*)x)->free == YFREE) : (0)) 83 | # define IS_RED(x) ((x) ? (((t_rbnode*)x)->color == RED) : (0)) 84 | # define MY_COMPARE(k1, k2) (((k1 == k2) ? (0) : ((k1 < k2) ? (-1) : (1)))) 85 | 86 | extern const char *__progname; 87 | 88 | t_rbnode *remove_from_freed_list(t_rbnode *root_rbtree, 89 | t_metadata *meta); 90 | t_rbnode *insert_in_freed_list(t_rbnode *node, t_metadata *new); 91 | void *get_heap(size_t size); 92 | void *calloc(size_t nmemb, size_t size); 93 | void *realloc(void *ptr, size_t size); 94 | t_metadata *fusion(t_metadata *first, t_metadata *second); 95 | void flip_color(t_rbnode *node); 96 | t_rbnode *rotate_left(t_rbnode *node); 97 | t_rbnode *rotate_right(t_rbnode *node); 98 | t_rbnode *new_rbtree(t_metadata *node); 99 | int resize_tab_values(t_metadata **old, t_rbnode *node); 100 | void flip_color(t_rbnode *node); 101 | t_rbnode *get_key(t_rbnode *node, t_key key); 102 | t_rbnode *min(t_rbnode *node); 103 | t_rbnode *balance_me_that(t_rbnode *node); 104 | t_rbnode *move_red_to_left(t_rbnode *node); 105 | t_rbnode *move_red_to_right(t_rbnode *node); 106 | void flip_color(t_rbnode *node); 107 | t_rbnode *remove_key(t_rbnode *node, t_key key); 108 | 109 | #endif /* !RBTREE_H_ */ 110 | -------------------------------------------------------------------------------- /rbtree/flip_color.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** flip_color.c for epitech in /home/chapui_s/travaux/malloc/ 3 | ** 4 | ** Made by chapui_s 5 | ** Login 6 | ** 7 | ** Started on Sun Feb 15 21:18:23 2015 chapui_s 8 | ** Last update Sun Feb 15 23:13:11 2015 chapui_s 9 | */ 10 | 11 | #include "rbtree.h" 12 | 13 | void flip_color(t_rbnode *node) 14 | { 15 | node->color = !(node->color); 16 | node->left->color = !(node->left->color); 17 | node->right->color = !(node->right->color); 18 | } 19 | -------------------------------------------------------------------------------- /rbtree/insert.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** rbtree.c for epitech in /home/chapui_s/travaux/malloc/ 3 | ** 4 | ** Made by chapui_s 5 | ** Login 6 | ** 7 | ** Started on Mon Feb 2 15:48:40 2015 chapui_s 8 | ** Last update Sun Feb 15 23:13:46 2015 chapui_s 9 | */ 10 | 11 | #include "rbtree.h" 12 | 13 | static int insert_node(t_rbnode *node, t_metadata *new) 14 | { 15 | t_metadata **tmp; 16 | size_t i; 17 | size_t size; 18 | 19 | i = 0; 20 | tmp = node->tab_values; 21 | size = node->size_tab; 22 | if (node->nb_activ == size) 23 | { 24 | i = node->nb_activ; 25 | if ((resize_tab_values(tmp, node)) == -1) 26 | return (0); 27 | } 28 | else 29 | { 30 | while (i < size && tmp[i]) 31 | i += 1; 32 | } 33 | node->nb_activ += 1; 34 | node->tab_values[i] = new; 35 | return (1); 36 | } 37 | 38 | static t_rbnode *insert_this(t_rbnode *node, t_metadata *new) 39 | { 40 | int res; 41 | 42 | if (!node) 43 | return (new_rbtree(new)); 44 | res = MY_COMPARE(new->size, node->key); 45 | if (res == 0) 46 | { 47 | if (insert_node(node, new) == 0) 48 | return ((t_rbnode*)0); 49 | } 50 | else if (res < 0) 51 | node->left = insert_this(node->left, new); 52 | else 53 | node->right = insert_this(node->right, new); 54 | if (IS_RED(node->right) && !IS_RED(node->left)) 55 | node = rotate_left(node); 56 | if (IS_RED(node->left) && IS_RED(node->left->left)) 57 | node = rotate_right(node); 58 | if (IS_RED(node->left) && IS_RED(node->right)) 59 | flip_color(node); 60 | return (node); 61 | } 62 | 63 | t_rbnode *insert_in_freed_list(t_rbnode *node, t_metadata *new) 64 | { 65 | node = insert_this(node, new); 66 | if (node) 67 | node->color = BLACK; 68 | new->free = YFREE; 69 | return (node); 70 | } 71 | -------------------------------------------------------------------------------- /rbtree/insert_utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** insert_utils.c for epitech in /home/chapui_s/travaux/malloc_ok/rbtree/ 3 | ** 4 | ** Made by chapui_s 5 | ** Login 6 | ** 7 | ** Started on Sun Feb 15 20:56:17 2015 chapui_s 8 | ** Last update Sun Feb 15 20:56:47 2015 chapui_s 9 | */ 10 | 11 | #include "rbtree.h" 12 | 13 | t_rbnode g_rbnode_basis = { 14 | 0, 15 | YFREE, 16 | (t_metadata*)0, 17 | (t_metadata*)0, 18 | 0, 19 | (t_value**)0, 20 | SIZE_TAB_VALUES, 21 | 1, 22 | RED, 23 | (t_rbnode*)0, 24 | (t_rbnode*)0 25 | }; 26 | 27 | static void *alloc_tab(size_t size) 28 | { 29 | void *new; 30 | size_t true_size; 31 | 32 | true_size = ALIGN_BYTES(META_SIZE + (sizeof(new) * size)); 33 | new = get_heap(true_size); 34 | if (new) 35 | bzero(GET_PAYLOAD(new), true_size - META_SIZE); 36 | return (new); 37 | } 38 | 39 | t_rbnode *new_rbtree(t_metadata *node) 40 | { 41 | t_rbnode *new; 42 | 43 | if ((new = get_heap(ALIGN_BYTES(sizeof(*new)))) == (t_rbnode*)0) 44 | return ((t_rbnode*)0); 45 | memcpy(&(new->size_tab) , &(g_rbnode_basis.size_tab), sizeof(size_t) * 5); 46 | new->key = node->size; 47 | if ((new->tab_values = GET_PAYLOAD(alloc_tab(SIZE_TAB_VALUES))) 48 | == (void*)META_SIZE) 49 | return ((t_rbnode*)0); 50 | new->tab_values[0] = node; 51 | return (new); 52 | } 53 | 54 | int resize_tab_values(t_metadata **old, t_rbnode *node) 55 | { 56 | t_metadata **new; 57 | size_t size; 58 | 59 | size = (node->size_tab) << 1; 60 | if ((new = GET_PAYLOAD(alloc_tab(size))) == (void*)META_SIZE) 61 | return (-1); 62 | memcpy(new, old, (size >> 1) * sizeof(*new)); 63 | ((t_metadata*)GET_NODE(node->tab_values))->free = YFREE; 64 | node->tab_values = new; 65 | node->size_tab = size; 66 | return (0); 67 | } 68 | -------------------------------------------------------------------------------- /rbtree/remove.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** remove.c for epitech in /home/chapui_s/travaux/malloc_ok/rbtree/ 3 | ** 4 | ** Made by chapui_s 5 | ** Login 6 | ** 7 | ** Started on Sun Feb 15 21:04:49 2015 chapui_s 8 | ** Last update Sun Feb 15 23:17:01 2015 chapui_s 9 | */ 10 | 11 | #include "rbtree.h" 12 | 13 | static t_rbnode *remove_min(t_rbnode *node) 14 | { 15 | if (!node) 16 | return ((t_rbnode*)0); 17 | if (!node->left) 18 | { 19 | node->free = YFREE; 20 | return ((t_rbnode*)0); 21 | } 22 | if (!IS_RED(node->left) && !IS_RED(node->left->left)) 23 | node = move_red_to_left(node); 24 | node->left = remove_min(node->left); 25 | return (balance_me_that(node)); 26 | } 27 | 28 | static t_rbnode *remove_node(t_rbnode *node, t_key key, t_rbnode *tmp) 29 | { 30 | if (IS_RED(node->left)) 31 | node = rotate_right(node); 32 | if (!MY_COMPARE(key, node->key) && !node->right) 33 | { 34 | node->free = YFREE; 35 | return ((t_rbnode*)0); 36 | } 37 | if (node->right) 38 | { 39 | if (!IS_RED(node->right) && !IS_RED(node->right->left)) 40 | node = move_red_to_right(node); 41 | if (!MY_COMPARE(key, node->key)) 42 | { 43 | tmp = min(node->right); 44 | node->tab_values = tmp->tab_values; 45 | node->size_tab = tmp->size_tab; 46 | node->key = tmp->key; 47 | node->right = remove_min(node->right); 48 | node->nb_activ = tmp->nb_activ; 49 | } 50 | else 51 | node->right = remove_key(node->right, key); 52 | } 53 | return (node); 54 | } 55 | 56 | t_rbnode *remove_key(t_rbnode *node, t_key key) 57 | { 58 | t_rbnode *tmp; 59 | 60 | if (!node) 61 | return ((t_rbnode*)0); 62 | if (MY_COMPARE(key, node->key) == -1) 63 | { 64 | if (node->left) 65 | { 66 | if (!IS_RED(node->left) && !IS_RED(node->left->left)) 67 | node = move_red_to_left(node); 68 | node->left = remove_key(node->left, key); 69 | } 70 | } 71 | else 72 | if ((node = remove_node(node, key, tmp)) == (void*)0) 73 | return ((void*)0); 74 | return (balance_me_that(node)); 75 | } 76 | 77 | static t_rbnode *remove_k(t_rbnode *node, t_key key) 78 | { 79 | node = remove_key(node, key); 80 | if (node) 81 | node->color = BLACK; 82 | return (node); 83 | } 84 | 85 | t_rbnode *remove_from_freed_list(t_rbnode *node, 86 | t_metadata *meta) 87 | { 88 | t_rbnode *tmp; 89 | t_metadata **tab; 90 | size_t i; 91 | size_t size; 92 | 93 | if ((tmp = get_key(node, meta->size))) 94 | { 95 | meta->free = NFREE; 96 | tab = tmp->tab_values; 97 | i = 0; 98 | size = tmp->size_tab; 99 | while (i < size) 100 | { 101 | if (tab[i] == meta) 102 | { 103 | tab[i] = (t_metadata*)0; 104 | tmp->nb_activ -= 1; 105 | if (tmp->nb_activ == 0) 106 | return (remove_k(node, meta->size)); 107 | return (node); 108 | } 109 | i += 1; 110 | } 111 | } 112 | return ((t_rbnode*)0); 113 | } 114 | -------------------------------------------------------------------------------- /rbtree/remove_utils.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** rbtree.c for epitech in /home/chapui_s/travaux/my_malloc2/rbtree.c 3 | ** 4 | ** Made by chapui_s 5 | ** Login 6 | ** 7 | ** Started on Mon Feb 2 15:48:40 2015 chapui_s 8 | ** Last update Sun Feb 15 21:19:24 2015 chapui_s 9 | */ 10 | 11 | #include "rbtree.h" 12 | 13 | t_rbnode *get_key(t_rbnode *node, t_key key) 14 | { 15 | int cmp; 16 | 17 | while (node) 18 | { 19 | if (!(cmp = MY_COMPARE(key, node->key))) 20 | return (node); 21 | node = ((cmp < 0) ? (node->left) : (node->right)); 22 | } 23 | return ((t_rbnode*)0); 24 | } 25 | 26 | t_rbnode *min(t_rbnode *node) 27 | { 28 | if (!node) 29 | return ((t_rbnode*)0); 30 | while (node->left) 31 | node = node->left; 32 | return (node); 33 | } 34 | 35 | t_rbnode *balance_me_that(t_rbnode *node) 36 | { 37 | if (IS_RED(node->right)) 38 | node = rotate_left(node); 39 | if (IS_RED(node->left) && IS_RED(node->left->left)) 40 | node = rotate_right(node); 41 | if (IS_RED(node->left) && IS_RED(node->right)) 42 | flip_color(node); 43 | return (node); 44 | } 45 | 46 | t_rbnode *move_red_to_left(t_rbnode *node) 47 | { 48 | flip_color(node); 49 | if (node && node->right && IS_RED(node->right->left)) 50 | { 51 | node->right = rotate_right(node->right); 52 | node = rotate_left(node); 53 | flip_color(node); 54 | } 55 | return (node); 56 | } 57 | 58 | t_rbnode *move_red_to_right(t_rbnode *node) 59 | { 60 | flip_color(node); 61 | if (node && node->left && IS_RED(node->left->left)) 62 | { 63 | node = rotate_right(node); 64 | flip_color(node); 65 | } 66 | return (node); 67 | } 68 | -------------------------------------------------------------------------------- /rbtree/rotate.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** rotate.c for epitech in /home/chapui_s/travaux/malloc_ok/rbtree/rotate.c 3 | ** 4 | ** Made by chapui_s 5 | ** Login 6 | ** 7 | ** Started on Sun Feb 15 20:45:53 2015 chapui_s 8 | ** Last update Sun Feb 15 20:45:55 2015 chapui_s 9 | */ 10 | 11 | #include "rbtree.h" 12 | 13 | t_rbnode *rotate_left(t_rbnode *left) 14 | { 15 | t_rbnode *right; 16 | 17 | if (!left) 18 | return ((t_rbnode*)0); 19 | right = left->right; 20 | left->right = right->left; 21 | right->left = left; 22 | right->color = left->color; 23 | left->color = RED; 24 | return (right); 25 | } 26 | 27 | t_rbnode *rotate_right(t_rbnode *right) 28 | { 29 | t_rbnode *left; 30 | 31 | if(!right) 32 | return ((t_rbnode*)0); 33 | left = right->left; 34 | right->left = left->right; 35 | left->right = right; 36 | left->color = right->color; 37 | right->color = RED; 38 | return (left); 39 | } 40 | -------------------------------------------------------------------------------- /realloc.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** malloc.c for epitech in /home/chapui_s/travaux/malloc/ 3 | ** 4 | ** Made by chapui_s 5 | ** Login 6 | ** 7 | ** Started on Mon Feb 2 15:52:40 2015 chapui_s 8 | ** Last update Sun Feb 15 23:07:01 2015 chapui_s 9 | */ 10 | 11 | #include "malloc.h" 12 | 13 | extern t_malloc g_info; 14 | 15 | void *free_realloc(void *ptr) 16 | { 17 | free(ptr); 18 | return ((void*)0); 19 | } 20 | 21 | void *realloc(void *ptr, size_t size) 22 | { 23 | t_metadata *new; 24 | t_metadata *tmp; 25 | 26 | if (!ptr) 27 | return (malloc(size)); 28 | if (!size) 29 | return (free_realloc(ptr)); 30 | ptr = (void*)ptr - META_SIZE; 31 | tmp = (t_metadata*)ptr; 32 | new = ptr; 33 | if (size + META_SIZE > tmp->size) 34 | { 35 | if ((new = malloc(size)) == (void*)0) 36 | return ((void*)0); 37 | size = ALIGN_BYTES(size); 38 | pthread_mutex_lock(&(g_info.mutex)); 39 | memcpy(new, (void*)ptr + META_SIZE, (size <= tmp->size) ? 40 | (size) : (tmp->size)); 41 | pthread_mutex_unlock(&(g_info.mutex)); 42 | free((void*)ptr + META_SIZE); 43 | } 44 | else 45 | new = GET_PAYLOAD(new); 46 | return (new); 47 | } 48 | -------------------------------------------------------------------------------- /show_alloc_mem.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** show_alloc_mem.c for epitech in /home/chapui_s/travaux/malloc/ 3 | ** 4 | ** Made by chapui_s 5 | ** Login 6 | ** 7 | ** Started on Sun Feb 15 19:56:20 2015 chapui_s 8 | ** Last update Sun Feb 15 23:08:53 2015 chapui_s 9 | */ 10 | 11 | #include "malloc.h" 12 | 13 | extern t_malloc g_info; 14 | 15 | void show_alloc_mem(void) 16 | { 17 | t_metadata *tmp; 18 | 19 | tmp = g_info.first_block; 20 | printf("break : %p\n", sbrk(0)); 21 | while (tmp) 22 | { 23 | if (tmp->free == NFREE) 24 | #ifdef __x86_64__ 25 | printf("%p - %p : %lu octets\n", 26 | #else /* !__x86_64__ */ 27 | printf("%p - %p : %d octets\n", 28 | #endif /* !__x86_64__ */ 29 | GET_PAYLOAD(tmp), 30 | (GET_PAYLOAD(tmp) + tmp->size - META_SIZE), 31 | tmp->size - META_SIZE); 32 | tmp = tmp->next; 33 | } 34 | } 35 | --------------------------------------------------------------------------------