Merge malloc with full history

This commit is contained in:
Jack 2026-01-29 18:05:07 -03:00
commit 257498d4f6
No known key found for this signature in database
29 changed files with 1110 additions and 0 deletions

8
malloc/.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
myprogram
*.o
libft_malloc_*.so
libft_malloc.so
tests/*
!test/*.c
!test/*.sh
.bin

3
malloc/.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "libft"]
path = libft
url = ../libft

114
malloc/Makefile Normal file
View file

@ -0,0 +1,114 @@
# **************************************************************************** #
# #
# ::: :::::::: #
# Makefile :+: :+: :+: #
# +:+ +:+ +:+ #
# By: wescande <wescande@student.42.fr> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# 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)

1
malloc/auteur Normal file
View file

@ -0,0 +1 @@
jhalford

11
malloc/do_test.sh Executable file
View file

@ -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

30
malloc/includes/malloc.h Normal file
View file

@ -0,0 +1,30 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* malloc.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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

View file

@ -0,0 +1,129 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* malloc_internal.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <sys/mman.h>
# include <stdalign.h>
# include <unistd.h>
# include <pthread.h>
# 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

27
malloc/srcs/calloc.c Normal file
View file

@ -0,0 +1,27 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* calloc.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

37
malloc/srcs/error_lib.c Normal file
View file

@ -0,0 +1,37 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* error_lib.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

62
malloc/srcs/free.c Normal file
View file

@ -0,0 +1,62 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* free.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/02/17 12:28:03 by jhalford #+# #+# */
/* Updated: 2017/10/23 19:32:20 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "malloc_internal.h"
#include <dlfcn.h>
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);
}

28
malloc/srcs/ft_memcpy.c Normal file
View file

@ -0,0 +1,28 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_memcpy.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

23
malloc/srcs/ft_memset.c Normal file
View file

@ -0,0 +1,23 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_memset.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

23
malloc/srcs/ft_putchar.c Normal file
View file

@ -0,0 +1,23 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_putchar.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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));
}

44
malloc/srcs/ft_putnbr.c Normal file
View file

@ -0,0 +1,44 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_putnbr.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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));
}

49
malloc/srcs/ft_putstr.c Normal file
View file

@ -0,0 +1,49 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_putstr.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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)));
}

53
malloc/srcs/hexdump.c Normal file
View file

@ -0,0 +1,53 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* hexdump.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

56
malloc/srcs/interface.c Normal file
View file

@ -0,0 +1,56 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* interface.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

View file

@ -0,0 +1,59 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* interface_extended.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

72
malloc/srcs/malloc.c Normal file
View file

@ -0,0 +1,72 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* malloc.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

66
malloc/srcs/node_lib.c Normal file
View file

@ -0,0 +1,66 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* insert_node.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

29
malloc/srcs/realloc.c Normal file
View file

@ -0,0 +1,29 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* realloc.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

24
malloc/srcs/reallocf.c Normal file
View file

@ -0,0 +1,24 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* reallocf.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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);
}

View file

@ -0,0 +1,56 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* show_alloc_mem.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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;
}
}

15
malloc/tests/test0.c Normal file
View file

@ -0,0 +1,15 @@
#include "../includes/malloc.h"
#include <stdio.h>
int main(void)
{
int i;
char *addr;
i = 0;
while (i < 1024)
{
i++;
}
return (0);
}

17
malloc/tests/test1.c Normal file
View file

@ -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);
}

17
malloc/tests/test2.c Normal file
View file

@ -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);
}

25
malloc/tests/test3.c Normal file
View file

@ -0,0 +1,25 @@
#include "../includes/malloc.h"
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#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);
}

20
malloc/tests/test4.c Normal file
View file

@ -0,0 +1,20 @@
#include "../includes/malloc.h"
#include <unistd.h>
#include <string.h>
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);
}

12
malloc/tests/test5.c Normal file
View file

@ -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);
}