diff --git a/malloc/.gitignore b/malloc/.gitignore new file mode 100644 index 00000000..b804db92 --- /dev/null +++ b/malloc/.gitignore @@ -0,0 +1,8 @@ +myprogram +*.o +libft_malloc_*.so +libft_malloc.so +tests/* +!test/*.c +!test/*.sh +.bin diff --git a/malloc/.gitmodules b/malloc/.gitmodules new file mode 100644 index 00000000..49141b44 --- /dev/null +++ b/malloc/.gitmodules @@ -0,0 +1,3 @@ +[submodule "libft"] + path = libft + url = ../libft diff --git a/malloc/Makefile b/malloc/Makefile new file mode 100644 index 00000000..e7a9693e --- /dev/null +++ b/malloc/Makefile @@ -0,0 +1,114 @@ +# **************************************************************************** # +# # +# ::: :::::::: # +# Makefile :+: :+: :+: # +# +:+ +:+ +:+ # +# By: wescande +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# Created: 2016/08/29 21:32:58 by wescande #+# #+# # +# Updated: 2017/10/22 13:19:38 by jhalford ### ########.fr # +# # +# **************************************************************************** # + +ifeq ($(HOSTTYPE),) + HOSTTYPE := $(shell uname -m)_$(shell uname -s) +endif + +NAME_BIS = libft_malloc.so +NAME = libft_malloc_$(HOSTTYPE).so + +CC = gcc +FLAGS = -Wall -Wextra -Werror -fvisibility=hidden -fPIC +MAIN_FLAGS = -shared -fPIC +OBJ_FLAGS = + +LEN_NAME = `printf "%s" $(NAME) |wc -c` +DELTA = $$(echo "$$(tput cols)-31-$(LEN_NAME)"|bc) + +SRC_DIR = srcs/ +INC_DIR = includes/ +OBJ_DIR = objs/ + +SRC_BASE = \ +calloc.c\ +error_lib.c\ +free.c\ +ft_memcpy.c\ +ft_memset.c\ +ft_putchar.c\ +ft_putnbr.c\ +ft_putstr.c\ +hexdump.c\ +interface.c\ +interface_extended.c\ +malloc.c\ +node_lib.c\ +realloc.c\ +reallocf.c\ +show_alloc_mem.c + +SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE)) +OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o)) +NB = $(words $(SRC_BASE)) +INDEX = 0 + +SHELL := /bin/bash + +all : + @make -j $(NAME) + @make $(NAME_BIS) + +$(NAME): $(OBJ_DIR) $(OBJS) + @$(CC) $(OBJS) -o $(NAME) \ + -I $(INC_DIR) \ + $(LIBS) $(MAIN_FLAGS) $(FLAGS) + @strip -x $@ + @printf "\r\033[38;5;117m✓ MAKE $(NAME)\033[0m\033[K\n" + +$(NAME_BIS): $(NAME) + @if [ -L $(NAME_BIS) ]; \ + then \ + rm $(NAME_BIS); \ + fi + @ln -s $(NAME) $(NAME_BIS) + @printf "\r\033[38;5;117m✓ LINK $(NAME_BIS)\033[0m\033[K\n" + +$(OBJ_DIR) : + @mkdir -p $(OBJ_DIR) + @mkdir -p $(dir $(OBJS)) + +$(OBJ_DIR)%.o : $(SRC_DIR)%.c | $(OBJ_DIR) + @$(eval DONE=$(shell echo $$(($(INDEX)*20/$(NB))))) + @$(eval PERCENT=$(shell echo $$(($(INDEX)*100/$(NB))))) + @$(eval TO_DO=$(shell echo $$((20-$(INDEX)*20/$(NB) - 1)))) + @$(eval COLOR=$(shell list=(160 196 202 208 215 221 226 227 190 154 118 82 46); index=$$(($(PERCENT) * $${#list[@]} / 100)); echo "$${list[$$index]}")) + @printf "\r\033[38;5;%dm⌛ [%s]: %2d%% `printf '█%.0s' {0..$(DONE)}`%*s❙%*.*s\033[0m\033[K" $(COLOR) $(NAME) $(PERCENT) $(TO_DO) "" $(DELTA) $(DELTA) "$(shell echo "$@" | sed 's/^.*\///')" + @$(CC) $(FLAGS) $(OBJ_FLAG) -MMD -c $< -o $@\ + -I $(INC_DIR) + @$(eval INDEX=$(shell echo $$(($(INDEX)+1)))) + +clean: cleanlib + @if [ -e $(OBJ_DIR) ]; \ + then \ + rm -rf $(OBJ_DIR); \ + printf "\r\033[38;5;202m✗ clean $(NAME).\033[0m\033[K\n"; \ + fi; + +fclean: clean fcleanlib + @if [ -e $(NAME) ]; \ + then \ + rm -rf $(NAME); \ + printf "\r\033[38;5;196m✗ fclean $(NAME).\033[0m\033[K\n"; \ + fi; + @if [ -L $(NAME_BIS) ]; \ + then \ + rm -rf $(NAME_BIS); \ + printf "\r\033[38;5;196m✗ delete link $(NAME_BIS).\033[0m\033[K\n"; \ + fi; + @$(foreach n, $(shell echo libft_malloc_*.so), if [ -f $n ]; then rm -rf $n; printf "\r\033[38;5;196m✗ delete old lib $n.\033[0m\033[K\n"; fi;) + +re: fclean all + +.PHONY : fclean clean re relib cleanlib fcleanlib tests + +-include $(OBJS:.o=.d) diff --git a/malloc/auteur b/malloc/auteur new file mode 100644 index 00000000..b0e9923f --- /dev/null +++ b/malloc/auteur @@ -0,0 +1 @@ +jhalford diff --git a/malloc/do_test.sh b/malloc/do_test.sh new file mode 100755 index 00000000..e57343a6 --- /dev/null +++ b/malloc/do_test.sh @@ -0,0 +1,11 @@ +if [ -z $1 ] +then + echo "Need an arg"; + exit; +fi +if [ -z $2 ] +then + make && gcc -w -L. $1 -o .bin -lft_malloc && /usr/bin/time -l ./.bin +else + make && gcc -w -L. $1 -o .bin -lft_malloc && ./tests/run.sh /usr/bin/time -l ./.bin +fi diff --git a/malloc/includes/malloc.h b/malloc/includes/malloc.h new file mode 100644 index 00000000..9b12cb46 --- /dev/null +++ b/malloc/includes/malloc.h @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* malloc.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/17 23:00:06 by jhalford #+# #+# */ +/* Updated: 2017/10/22 17:36:27 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FT_MALLOC_H +# define FT_MALLOC_H + +# include "stdlib.h" + +# pragma GCC visibility push(default) + +void free(void *ptr); +void *malloc(size_t size); +void *realloc(void *ptr, size_t size); +void *reallocf(void *ptr, size_t size); +void *calloc(size_t count, size_t size); +void show_alloc_mem(void); +void dump_alloc_mem(void); + +# pragma GCC visibility pop + +#endif diff --git a/malloc/includes/malloc_internal.h b/malloc/includes/malloc_internal.h new file mode 100644 index 00000000..17fe3c59 --- /dev/null +++ b/malloc/includes/malloc_internal.h @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* malloc_internal.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/17 23:00:24 by jhalford #+# #+# */ +/* Updated: 2017/10/22 17:17:13 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef MALLOC_INTERNAL_H +# define MALLOC_INTERNAL_H + +# define M_NTINY ((size_t)64) +# define M_NSMALL ((size_t)1024) +# define M_PAGEALIGN(x) ((x / getpagesize() + 1) * getpagesize()) * 10 +# define M_TINYCHUNK (M_PAGEALIGN(101 * M_NTINY)) +# define M_SMALLCHUNK (M_PAGEALIGN(101 * M_NSMALL)) +# define M_CHUNKHEAD (sizeof(t_chunk)) +# define M_NODEHEAD (sizeof(t_node)) +# define M_ISTINY(x) (x < (M_NTINY + 1)) +# define M_ISSMALL(x) (!M_ISTINY(x) && !M_ISLARGE(x)) +# define M_ISLARGE(x) (M_NSMALL < x) +# define NEXT(node) (node->islast ? NULL : (void*)node + node->size) + +# define FT_ABS(x) (((x) < 0) ? -(x) : x) + +# define DP_N(n) ft_putnbr_fd(n, 2) +# define DP_H(n) ft_putnbr_hex_fd(n, 2) +# define DP_C(n) ft_putchar_fd(n, 2) +# define DP_S(n) ft_putstr_fd(n, 2) +# define DGPID DP_S("===");DP_N(getpid());DP_S("==="); +# define DGW(d) DGPID;d;DP_C('\n') +# define DGS(s) do { DGW(DP_S(" "s)); } while(0) +# define DGSN(s, n) do { DGW(DP_S(" "s"=");DP_N(n)); } while(0) +# define DGSH(s, n) do { DGW(DP_S(" "s"=");DP_H(n)); } while(0) + +# define FG_DEFAULT "\e[0m" +# define ON_BOLD "\e[1m" +# define ON_UNDERLINED "\e[4m" +# define ON_INVERTED "\e[7m" +# define FG_BLACK "\e[30m" +# define FG_RED "\e[31m" +# define FG_GREEN "\e[32m" +# define FG_YELLOW "\e[33m" +# define FG_BLUE "\e[34m" +# define FG_MAGENTA "\e[35m" +# define FG_CYAN "\e[36m" +# define BG_BLACK "\e[40m" +# define BG_RED "\e[41m" +# define BG_GREEN "\e[42m" +# define BG_YELLOW "\e[43m" +# define BG_BLUE "\e[44m" +# define BG_MAGENTA "\e[45m" +# define BG_CYAN "\e[46m" +# define BG_DEFAULT "\e[49m" +# define FBG_DEFAULT FG_DEFAULT BG_DEFAULT + +# include +# include +# include +# include +# include "malloc.h" + +typedef struct s_chunk { + struct s_chunk *next; +} t_chunk; + +typedef struct s_node { + size_t size; + unsigned int isfree:1; + unsigned int islast:1; +} t_node; + +enum e_zones { + M_TINY, + M_SMALL, + M_LARGE, + M_ZONES_MAX, +}; + +extern t_chunk *g_zones[M_ZONES_MAX]; +extern pthread_mutex_t g_mutex; +extern int g_malloc_debug; +/* +** malloc_debug levels: +** 1: show malloc/free calls with arguments +** 2: show chunks before and after malloc/free, notify when coalescing. +** 3: show mmap values +*/ + +int ft_free(void *ptr); +void *ft_malloc(size_t size); +void *ft_realloc(void *ptr, size_t size); +void *ft_reallocf(void *ptr, size_t size); +void *ft_calloc(size_t count, size_t size); +int ret_free(void *ptr); + +t_chunk **get_zone(size_t size); +t_node *find_node_firstfit(t_chunk *chunk, size_t size); +t_node *find_prev_node(t_chunk *zone, t_node *node); +int split_node(t_node *node, size_t size); + +void *hexdump(void *addr, unsigned int offset, + unsigned int size); +void show_chunk(char *name, t_chunk *chunk, int dump); + +void error_mmap(void); +void error_free_notalloc(void *ptr); + +int ft_putchar(char c); +int ft_putchar_fd(char c, int fd); +int ft_putendl(char const *s); +int ft_putendl_fd(char const *s, int fd); +int ft_putstr(char const *s); +int ft_putstr_fd(char const *s, int fd); + +int ft_putnbr(long n); +int ft_putnbr_fd(long n, int fd); +int ft_putnbr_hex(long n); +int ft_putnbr_hex_fd(long n, int fd); +int ft_putnbr_loop(long n, int base, int fd); + +void *ft_memcpy(void *dst, const void *src, size_t n); +void *ft_memset(void *b, int c, size_t len); + +#endif diff --git a/malloc/srcs/calloc.c b/malloc/srcs/calloc.c new file mode 100644 index 00000000..56ae14df --- /dev/null +++ b/malloc/srcs/calloc.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* calloc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/10/22 14:35:06 by jhalford #+# #+# */ +/* Updated: 2017/10/22 18:44:24 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "malloc_internal.h" + +int g_malloc_debug; + +void *ft_calloc(size_t count, size_t size) +{ + void *ptr; + unsigned long big_size; + + big_size = count * size; + if (!(ptr = ft_malloc(big_size))) + return (ptr); + ft_memset(ptr, 0, big_size); + return (ptr); +} diff --git a/malloc/srcs/error_lib.c b/malloc/srcs/error_lib.c new file mode 100644 index 00000000..6cf825d6 --- /dev/null +++ b/malloc/srcs/error_lib.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* error_lib.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/18 19:34:23 by jhalford #+# #+# */ +/* Updated: 2017/10/22 11:29:39 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "malloc_internal.h" + +void error_free_notalloc(void *ptr) +{ + int fd; + + fd = 2; + ft_putstr_fd(FG_RED"(", fd); + ft_putnbr_fd(getpid(), fd); + ft_putstr_fd(")", fd); + ft_putstr_fd(" malloc: error for object ", fd); + ft_putnbr_hex_fd((long)ptr, fd); + ft_putendl_fd(": pointer being freed was not allocated"FG_DEFAULT, fd); +} + +void error_mmap(void) +{ + int fd; + + fd = 2; + ft_putstr_fd(FG_RED"(", fd); + ft_putnbr_fd(getpid(), fd); + ft_putstr_fd(")", fd); + ft_putendl_fd(" malloc: mmap failed", fd); +} diff --git a/malloc/srcs/free.c b/malloc/srcs/free.c new file mode 100644 index 00000000..9414e2ae --- /dev/null +++ b/malloc/srcs/free.c @@ -0,0 +1,62 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* free.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/17 12:28:03 by jhalford #+# #+# */ +/* Updated: 2017/10/23 19:32:20 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "malloc_internal.h" +#include + +int g_malloc_debug; +t_chunk *g_zones[M_ZONES_MAX]; + +int coalesce_nodes(t_node *node) +{ + t_node *next; + + if (node->islast) + return (0); + next = (void*)node + node->size; + if (node->isfree && next->isfree) + { + if (g_malloc_debug >= 2) + { + DGSH("coalescing 2 nodes at addr", (long)node); + DGSH("and addr", (long)next); + } + node->islast = next->islast; + node->size += next->size; + } + return (0); +} + +int ft_free(void *ptr) +{ + t_node *node; + t_node *prev; + + if (!ptr) + return (2); + if (g_malloc_debug >= 2) + show_alloc_mem(); + node = ptr - M_NODEHEAD; + if (!((prev = find_prev_node(g_zones[M_TINY], node)) + || (prev = find_prev_node(g_zones[M_SMALL], node)) + || (prev = find_prev_node(g_zones[M_LARGE], node)))) + { + if (g_malloc_debug >= 2) + error_free_notalloc(ptr); + return (1); + } + node->isfree = 1; + coalesce_nodes(prev); + if (g_malloc_debug >= 2) + show_alloc_mem(); + return (0); +} diff --git a/malloc/srcs/ft_memcpy.c b/malloc/srcs/ft_memcpy.c new file mode 100644 index 00000000..1754c420 --- /dev/null +++ b/malloc/srcs/ft_memcpy.c @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memcpy.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2016/11/03 14:57:31 by jhalford #+# #+# */ +/* Updated: 2017/10/22 12:46:59 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "malloc_internal.h" + +void *ft_memcpy(void *dst, const void *src, size_t n) +{ + char *c1; + char *c2; + + if (n == 0 || dst == src) + return (dst); + c1 = (char *)dst; + c2 = (char *)src; + while (--n) + *c1++ = *c2++; + *c1 = *c2; + return (dst); +} diff --git a/malloc/srcs/ft_memset.c b/malloc/srcs/ft_memset.c new file mode 100644 index 00000000..cf02288e --- /dev/null +++ b/malloc/srcs/ft_memset.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_memset.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/10/22 14:37:31 by jhalford #+# #+# */ +/* Updated: 2017/10/22 15:00:47 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "malloc_internal.h" + +void *ft_memset(void *b, int c, size_t len) +{ + size_t i; + + i = -1; + while (++i < len) + ((unsigned char *)b)[i] = (unsigned char)c; + return (b); +} diff --git a/malloc/srcs/ft_putchar.c b/malloc/srcs/ft_putchar.c new file mode 100644 index 00000000..e8b0e545 --- /dev/null +++ b/malloc/srcs/ft_putchar.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putchar.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/10/07 17:07:04 by jhalford #+# #+# */ +/* Updated: 2017/10/07 17:07:06 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "malloc_internal.h" + +int ft_putchar_fd(char c, int fd) +{ + return (write(fd, &c, 1)); +} + +int ft_putchar(char c) +{ + return (write(1, &c, 1)); +} diff --git a/malloc/srcs/ft_putnbr.c b/malloc/srcs/ft_putnbr.c new file mode 100644 index 00000000..eeb243dd --- /dev/null +++ b/malloc/srcs/ft_putnbr.c @@ -0,0 +1,44 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putnbr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/10/07 17:07:00 by jhalford #+# #+# */ +/* Updated: 2017/10/08 18:15:49 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "malloc_internal.h" + +int ft_putnbr_loop(long n, int base, int fd) +{ + if (n >= base) + ft_putnbr_loop(n / base, base, fd); + return (ft_putchar_fd("0123456789abcdef"[n % base], fd)); +} + +int ft_putnbr_hex_fd(long n, int fd) +{ + ft_putstr_fd("0x", fd); + return (ft_putnbr_loop(n, 16, fd)); +} + +int ft_putnbr_fd(long n, int fd) +{ + if (n < 0) + ft_putchar_fd('-', fd); + n = FT_ABS(n); + return (ft_putnbr_loop(n, 10, fd)); +} + +int ft_putnbr_hex(long n) +{ + return (ft_putnbr_hex_fd(n, 1)); +} + +int ft_putnbr(long n) +{ + return (ft_putnbr_fd(n, 1)); +} diff --git a/malloc/srcs/ft_putstr.c b/malloc/srcs/ft_putstr.c new file mode 100644 index 00000000..f09352b4 --- /dev/null +++ b/malloc/srcs/ft_putstr.c @@ -0,0 +1,49 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_putstr.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/10/07 17:07:41 by jhalford #+# #+# */ +/* Updated: 2017/10/22 15:30:37 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "malloc_internal.h" + +size_t ft_strlen(const char *s) +{ + int i; + + i = 0; + if (!s) + return (0); + while (s[i]) + i++; + return (i); +} + +int ft_putendl_fd(char const *s, int fd) +{ + char nl; + + nl = '\n'; + write(fd, s, ft_strlen(s)); + return (write(fd, &nl, 1)); +} + +int ft_putendl(char const *s) +{ + return (ft_putendl_fd(s, 1)); +} + +int ft_putstr_fd(char const *s, int fd) +{ + return (write(fd, s, ft_strlen(s))); +} + +int ft_putstr(char const *s) +{ + return (write(1, s, ft_strlen(s))); +} diff --git a/malloc/srcs/hexdump.c b/malloc/srcs/hexdump.c new file mode 100644 index 00000000..5316cc84 --- /dev/null +++ b/malloc/srcs/hexdump.c @@ -0,0 +1,53 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* hexdump.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/10/07 15:44:13 by jhalford #+# #+# */ +/* Updated: 2017/10/08 18:16:02 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "malloc_internal.h" + +int ft_dumpnbr_hex(char n) +{ + if (n < 0xa) + ft_putchar('0'); + return (ft_putnbr_loop(n, 16, 1)); +} + +static void print_hex_contents(void *addr, unsigned int size) +{ + void *a; + + a = addr; + while (a - addr < 16) + { + if ((a - addr) >= size) + break ; + else + ft_dumpnbr_hex(*(unsigned char*)a); + ft_putchar(' '); + a++; + } +} + +void *hexdump(void *addr, unsigned int offset, unsigned int size) +{ + void *a; + + addr += offset; + a = addr; + if (addr == NULL) + return (addr); + while ((a - addr) < size) + { + print_hex_contents(a, (size - (a - addr))); + ft_putchar('\n'); + a += 16; + } + return (addr); +} diff --git a/malloc/srcs/interface.c b/malloc/srcs/interface.c new file mode 100644 index 00000000..306a31ff --- /dev/null +++ b/malloc/srcs/interface.c @@ -0,0 +1,56 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* interface.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/10/22 13:25:32 by jhalford #+# #+# */ +/* Updated: 2017/10/23 19:41:14 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "malloc_internal.h" + +t_chunk *g_zones[M_ZONES_MAX] = +{ + NULL, + NULL, + NULL, +}; +int g_malloc_debug = 1; +pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; + +void *malloc(size_t size) +{ + void *new_ptr; + + pthread_mutex_lock(&g_mutex); + if (g_malloc_debug >= 1) + DGS("malloc called"); + new_ptr = ft_malloc(size); + pthread_mutex_unlock(&g_mutex); + return (new_ptr); +} + +void free(void *ptr) +{ + pthread_mutex_lock(&g_mutex); + if (g_malloc_debug >= 1) + DGS("free called"); + ft_free(ptr); + pthread_mutex_unlock(&g_mutex); + return ; +} + +void *realloc(void *ptr, size_t size) +{ + void *new_ptr; + + pthread_mutex_lock(&g_mutex); + if (g_malloc_debug >= 1) + DGS("realloc called"); + new_ptr = ft_realloc(ptr, size); + pthread_mutex_unlock(&g_mutex); + return (new_ptr); +} diff --git a/malloc/srcs/interface_extended.c b/malloc/srcs/interface_extended.c new file mode 100644 index 00000000..34aebd4c --- /dev/null +++ b/malloc/srcs/interface_extended.c @@ -0,0 +1,59 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* interface_extended.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/10/22 17:32:51 by jhalford #+# #+# */ +/* Updated: 2017/10/23 19:40:43 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "malloc_internal.h" + +t_chunk *g_zones[M_ZONES_MAX]; +int g_malloc_debug; +pthread_mutex_t g_mutex; + +void *reallocf(void *ptr, size_t size) +{ + void *new_ptr; + + pthread_mutex_lock(&g_mutex); + if (g_malloc_debug >= 1) + DGS("reallocf called"); + new_ptr = ft_reallocf(ptr, size); + pthread_mutex_unlock(&g_mutex); + return (new_ptr); +} + +void *calloc(size_t count, size_t size) +{ + void *new_ptr; + + pthread_mutex_lock(&g_mutex); + if (g_malloc_debug >= 1) + DGS("calloc called"); + new_ptr = ft_calloc(count, size); + pthread_mutex_unlock(&g_mutex); + return (new_ptr); +} + +void show_alloc_mem(void) +{ + pthread_mutex_lock(&g_mutex); + show_chunk("TINY: ", g_zones[M_TINY], 0); + show_chunk("SMALL: ", g_zones[M_SMALL], 0); + show_chunk("LARGE: ", g_zones[M_LARGE], 0); + pthread_mutex_unlock(&g_mutex); +} + +void dump_alloc_mem(void) +{ + pthread_mutex_lock(&g_mutex); + show_chunk("TINY: ", g_zones[M_TINY], 1); + show_chunk("SMALL: ", g_zones[M_SMALL], 1); + show_chunk("LARGE: ", g_zones[M_LARGE], 1); + pthread_mutex_unlock(&g_mutex); +} diff --git a/malloc/srcs/malloc.c b/malloc/srcs/malloc.c new file mode 100644 index 00000000..d04c44e9 --- /dev/null +++ b/malloc/srcs/malloc.c @@ -0,0 +1,72 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* malloc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/17 12:28:02 by jhalford #+# #+# */ +/* Updated: 2017/10/23 19:41:03 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "malloc_internal.h" + +t_chunk *g_zones[M_ZONES_MAX]; +int g_malloc_debug; +pthread_mutex_t g_mutex; + +t_chunk **get_zone(size_t size) +{ + if (M_ISLARGE(size)) + return (&g_zones[M_LARGE]); + else if (M_ISSMALL(size)) + return (&g_zones[M_SMALL]); + else + return (&g_zones[M_TINY]); +} + +void add_chunk(t_chunk **chunk, size_t size) +{ + int chunk_size; + t_chunk *new; + t_node *node; + + if (M_ISLARGE(size)) + chunk_size = M_PAGEALIGN(size); + else + chunk_size = M_ISTINY(size) ? M_TINYCHUNK : M_SMALLCHUNK; + chunk_size += M_CHUNKHEAD; + if (!(new = mmap(NULL, chunk_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0))) + error_mmap(); + if (g_malloc_debug >= 3) + DGSH("mmap returned", (long)new); + new->next = *chunk; + *chunk = new; + node = (t_node*)(*chunk + 1); + node->size = chunk_size - M_CHUNKHEAD; + node->isfree = 1; + node->islast = 1; +} + +void *ft_malloc(size_t size) +{ + t_chunk **zone; + t_node *node; + void *ret; + + if (g_malloc_debug >= 2) + show_alloc_mem(); + size += M_NODEHEAD; + zone = get_zone(size); + while (!(node = find_node_firstfit(*zone, size))) + add_chunk(zone, size); + split_node(node, size); + ret = (void*)(node + 1); + if (g_malloc_debug >= 1) + DGSH("user got ptr", (long)ret); + if (g_malloc_debug >= 2) + show_alloc_mem(); + return (ret); +} diff --git a/malloc/srcs/node_lib.c b/malloc/srcs/node_lib.c new file mode 100644 index 00000000..d0b43668 --- /dev/null +++ b/malloc/srcs/node_lib.c @@ -0,0 +1,66 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* insert_node.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/17 12:28:15 by jhalford #+# #+# */ +/* Updated: 2017/10/22 17:17:14 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "malloc_internal.h" + +t_node *find_node_firstfit(t_chunk *chunk, size_t size) +{ + t_node *node; + + if (!chunk) + return (NULL); + node = (t_node*)(chunk + 1); + while (node) + { + if (node->isfree && node->size >= size) + break ; + node = NEXT(node); + } + return (node); +} + +int split_node(t_node *node, size_t size) +{ + t_node *new_node; + + node->isfree = 0; + if (node->size - size <= M_NODEHEAD) + return (0); + new_node = (void*)node + size; + new_node->size = node->size - size; + new_node->isfree = 1; + new_node->islast = node->islast; + node->islast = 0; + node->size = size; + return (0); +} + +t_node *find_prev_node(t_chunk *zone, t_node *node) +{ + t_node *n; + t_node *prev; + + while (zone) + { + n = (t_node*)(zone + 1); + prev = n; + while (n) + { + if (n == node) + return (prev); + prev = n; + n = NEXT(n); + } + zone = zone->next; + } + return (NULL); +} diff --git a/malloc/srcs/realloc.c b/malloc/srcs/realloc.c new file mode 100644 index 00000000..0137f7a9 --- /dev/null +++ b/malloc/srcs/realloc.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* realloc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/18 13:23:20 by jhalford #+# #+# */ +/* Updated: 2017/10/22 17:28:05 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "malloc_internal.h" + +void *ft_realloc(void *ptr, size_t size) +{ + void *new; + size_t old_size; + + if (!ptr) + return (ft_malloc(size)); + if (ft_free(ptr)) + return (NULL); + old_size = ((t_node*)(ptr - M_NODEHEAD))->size; + if (!(new = ft_malloc(size))) + return (NULL); + ft_memcpy(new, ptr, old_size); + return (new); +} diff --git a/malloc/srcs/reallocf.c b/malloc/srcs/reallocf.c new file mode 100644 index 00000000..f17ae8f5 --- /dev/null +++ b/malloc/srcs/reallocf.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* reallocf.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/10/22 13:33:57 by jhalford #+# #+# */ +/* Updated: 2017/10/22 17:28:02 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "malloc_internal.h" + +extern pthread_mutex_t g_mutex; + +void *ft_reallocf(void *ptr, size_t size) +{ + void *new_ptr; + + if (!(new_ptr = ft_realloc(ptr, size))) + ft_free(ptr); + return (new_ptr); +} diff --git a/malloc/srcs/show_alloc_mem.c b/malloc/srcs/show_alloc_mem.c new file mode 100644 index 00000000..e586223b --- /dev/null +++ b/malloc/srcs/show_alloc_mem.c @@ -0,0 +1,56 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* show_alloc_mem.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/17 12:28:20 by jhalford #+# #+# */ +/* Updated: 2017/10/23 19:42:14 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "malloc_internal.h" + +t_chunk *g_zones[M_ZONES_MAX]; + +void print_node(char color[7], t_node *node) +{ + ft_putstr("\t"); + ft_putstr(color); + ft_putnbr_hex((long)(node)); + ft_putstr(" - "); + ft_putnbr_hex((long)(node + 1)); + ft_putstr(" - "); + ft_putnbr_hex((long)((void*)node + node->size)); + ft_putstr(FBG_DEFAULT" : "); + ft_putnbr(node->size); + ft_putstr(" bytes"); + ft_putchar('\n'); +} + +void show_chunk(char *name, t_chunk *chunk, int dump) +{ + t_node *node; + + ft_putstr(name); + if (!chunk) + { + ft_putstr("empty"); + ft_putchar('\n'); + return ; + } + while (chunk) + { + ft_putchar('\n'); + node = (t_node*)(chunk + 1); + while (node) + { + print_node(node->isfree ? FG_GREEN : FG_RED, node); + if (dump && !node->isfree) + hexdump(node, M_NODEHEAD, node->size - M_NODEHEAD); + node = NEXT(node); + } + chunk = chunk->next; + } +} diff --git a/malloc/tests/test0.c b/malloc/tests/test0.c new file mode 100644 index 00000000..d3120a9b --- /dev/null +++ b/malloc/tests/test0.c @@ -0,0 +1,15 @@ +#include "../includes/malloc.h" +#include + +int main(void) +{ + int i; + char *addr; + + i = 0; + while (i < 1024) + { + i++; + } + return (0); +} diff --git a/malloc/tests/test1.c b/malloc/tests/test1.c new file mode 100644 index 00000000..69d28f35 --- /dev/null +++ b/malloc/tests/test1.c @@ -0,0 +1,17 @@ +#include "../includes/malloc.h" + +void *malloc(size_t size); +int main(void) +{ + int i; + char *addr; + + i = 0; + while (i < 1024) + { + addr = (char*)malloc(1024); + addr[0] = 42; + i++; + } + return (0); +} diff --git a/malloc/tests/test2.c b/malloc/tests/test2.c new file mode 100644 index 00000000..c65bdc0e --- /dev/null +++ b/malloc/tests/test2.c @@ -0,0 +1,17 @@ +#include "../includes/malloc.h" + +int main(void) +{ + int i; + char *addr; + + i = 0; + while (i < 1024) + { + addr = (char*)malloc(1024); + addr[0] = 42; + free(addr); + i++; + } + return (0); +} diff --git a/malloc/tests/test3.c b/malloc/tests/test3.c new file mode 100644 index 00000000..8381fa06 --- /dev/null +++ b/malloc/tests/test3.c @@ -0,0 +1,25 @@ +#include "../includes/malloc.h" +#include +#include +#include + +#define M (1024 * 1024) + +void print(char *s) +{ + write(1, s, strlen(s)); +} + +int main(void) +{ + char *addr1; + char *addr3; + + addr1 = (char*)malloc(16*M); + strcpy(addr1, "Bonjours\n"); + print(addr1); + addr3 = (char*)realloc(addr1, 128*M); + addr3[127*M] = 42; + print(addr3); + return (0); +} diff --git a/malloc/tests/test4.c b/malloc/tests/test4.c new file mode 100644 index 00000000..9bb9f3d1 --- /dev/null +++ b/malloc/tests/test4.c @@ -0,0 +1,20 @@ +#include "../includes/malloc.h" +#include +#include + +void print(char *s) +{ + write(1, s, strlen(s)); +} + +int main(void) +{ + char *addr; + + addr = malloc(16); + free(NULL); + free((void*)addr + 5); + if (realloc((void*)addr + 5, 10) == NULL) + print("Bonjours\n"); + return (0); +} diff --git a/malloc/tests/test5.c b/malloc/tests/test5.c new file mode 100644 index 00000000..e01aadb9 --- /dev/null +++ b/malloc/tests/test5.c @@ -0,0 +1,12 @@ +#include "../includes/malloc.h" + +int main(void) +{ + malloc(1024); + malloc(1024 * 32); + malloc(1024 * 1024); + malloc(1024 * 1024 * 16); + malloc(1024 * 1024 * 128); + show_alloc_mem(); + return (0); +}