Compare commits
10 commits
a8eb47d8fe
...
0b4b3f5239
Author | SHA1 | Date | |
---|---|---|---|
0b4b3f5239 | |||
ce8b634aeb | |||
dc112a5b7e | |||
3fa3ff5304 | |||
80fedbeb03 | |||
71d3fde169 | |||
511d06a6ec | |||
55d5a485a3 | |||
902bc6d7f0 | |||
d806927b8c |
99 changed files with 952 additions and 207 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -3,3 +3,5 @@
|
||||||
*.so
|
*.so
|
||||||
.vscode
|
.vscode
|
||||||
/bld
|
/bld
|
||||||
|
/debug_bld
|
||||||
|
/out
|
||||||
|
|
165
Makefile
165
Makefile
|
@ -1,165 +0,0 @@
|
||||||
# **************************************************************************** #
|
|
||||||
# #
|
|
||||||
# ::: :::::::: #
|
|
||||||
# Makefile :+: :+: :+: #
|
|
||||||
# +:+ +:+ +:+ #
|
|
||||||
# By: gtertysh <marvin@42.fr> +#+ +:+ +#+ #
|
|
||||||
# +#+#+#+#+#+ +#+ #
|
|
||||||
# Created: 2018/02/18 16:06:01 by gtertysh #+# #+# #
|
|
||||||
# Updated: 2019/01/19 15:21:01 by gtertysh ### ########.fr #
|
|
||||||
# #
|
|
||||||
# **************************************************************************** #
|
|
||||||
|
|
||||||
ifeq ($(HOSTTYPE),)
|
|
||||||
HOSTTYPE := $(shell uname -m)_$(shell uname -s)
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
# name of the main target
|
|
||||||
|
|
||||||
NAME := libft_malloc_$(HOSTTYPE).so
|
|
||||||
|
|
||||||
|
|
||||||
# project directories
|
|
||||||
|
|
||||||
ROOT := $(shell pwd)
|
|
||||||
SRC_DIR := $(ROOT)/src/
|
|
||||||
OBJ_DIR := $(ROOT)/obj/
|
|
||||||
INC_DIR := $(ROOT)/inc/
|
|
||||||
LIB_DIR := $(ROOT)/lib/
|
|
||||||
TST_DIR := $(ROOT)/t/
|
|
||||||
|
|
||||||
|
|
||||||
# project headers
|
|
||||||
|
|
||||||
MLC_HEADER := $(INC_DIR)/ft_malloc.h
|
|
||||||
TST_HEADER := $(INC_DIR)/tests.h
|
|
||||||
TST_RUNNER_HEADER := $(INC_DIR)/t.h
|
|
||||||
HEADERS := $(MLC_HEADER) \
|
|
||||||
$(TST_HEADER) \
|
|
||||||
$(TST_RUNNER_HEADER)
|
|
||||||
|
|
||||||
|
|
||||||
# libraries
|
|
||||||
|
|
||||||
LIBFT_DIR := $(LIB_DIR)libft/
|
|
||||||
LIBFT_INC := -I $(LIBFT_DIR)includes/
|
|
||||||
LIBFT_LIB := -lft -L $(LIBFT_DIR)
|
|
||||||
LIBFT = $(LIBFT_DIR)libft.a
|
|
||||||
|
|
||||||
|
|
||||||
# project source files
|
|
||||||
|
|
||||||
MALLOC_SRC = malloc.c
|
|
||||||
|
|
||||||
SRC := $(MALLOC_SRC)
|
|
||||||
|
|
||||||
|
|
||||||
# project object files
|
|
||||||
|
|
||||||
OBJ = $(addprefix $(OBJ_DIR), $(SRC:.c=.o))
|
|
||||||
|
|
||||||
|
|
||||||
# project test files
|
|
||||||
|
|
||||||
TEST_BIN = malloc_test
|
|
||||||
|
|
||||||
MALLOC_TESTS = malloc_tests.c
|
|
||||||
MALLOC_TESTS += $(MALLOC_SRC)
|
|
||||||
|
|
||||||
TEST_SRC = tests.c \
|
|
||||||
$(MALLOC_TESTS)
|
|
||||||
|
|
||||||
TEST_OBJ = $(addprefix $(OBJ_DIR), $(TEST_SRC:.c=.o))
|
|
||||||
|
|
||||||
|
|
||||||
# compilation flags
|
|
||||||
|
|
||||||
CC_FLAGS = -Wall -Wextra -Werror
|
|
||||||
|
|
||||||
CC_FLAGS += -Wpointer-arith
|
|
||||||
CC_FLAGS += -Wcast-align
|
|
||||||
CC_FLAGS += -Wwrite-strings
|
|
||||||
CC_FLAGS += -Wunreachable-code
|
|
||||||
CC_FLAGS += -Winit-self
|
|
||||||
CC_FLAGS += -Wmissing-field-initializers
|
|
||||||
CC_FLAGS += -Wno-unknown-pragmas
|
|
||||||
CC_FLAGS += -Wstrict-prototypes
|
|
||||||
CC_FLAGS += -Wundef
|
|
||||||
CC_FLAGS += -Wold-style-definition
|
|
||||||
|
|
||||||
|
|
||||||
# for debug
|
|
||||||
|
|
||||||
ifeq ($(DEBUG),true)
|
|
||||||
|
|
||||||
CC_FLAGS += -g
|
|
||||||
CC_FLAGS += -O0
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
# linking flags
|
|
||||||
|
|
||||||
LINK_FLAGS = $(LIBFT_LIB)
|
|
||||||
|
|
||||||
|
|
||||||
# header flags
|
|
||||||
|
|
||||||
HEADER_FLAGS = -I $(INC_DIR) \
|
|
||||||
$(LIBFT_INC)
|
|
||||||
|
|
||||||
|
|
||||||
# compiler
|
|
||||||
|
|
||||||
CC := clang
|
|
||||||
|
|
||||||
|
|
||||||
# rules
|
|
||||||
|
|
||||||
$(NAME): $(OBJ)
|
|
||||||
$(CC) -shared $(OBJ) -o $(NAME) $(LINK_FLAGS)
|
|
||||||
|
|
||||||
$(TEST_BIN): $(TEST_OBJ)
|
|
||||||
$(CC) $(TEST_OBJ) $(LINK_FLAGS) -o $(TEST_BIN)
|
|
||||||
|
|
||||||
$(TEST_OBJ) $(OBJ): | $(OBJ_DIR)
|
|
||||||
|
|
||||||
$(OBJ_DIR):
|
|
||||||
mkdir $(OBJ_DIR)
|
|
||||||
|
|
||||||
$(OBJ_DIR)%.o: %.c $(LIBFT) $(HEADERS)
|
|
||||||
$(CC) -fpic -c $< -o $@ $(CC_FLAGS) $(HEADER_FLAGS)
|
|
||||||
|
|
||||||
$(LIBFT):
|
|
||||||
$(MAKE) -C $(LIBFT_DIR)
|
|
||||||
|
|
||||||
all: $(NAME)
|
|
||||||
|
|
||||||
check: $(TEST_BIN)
|
|
||||||
clear
|
|
||||||
./$(TEST_BIN)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(OBJ)
|
|
||||||
rm -f $(TEST_OBJ)
|
|
||||||
$(MAKE) -C $(LIBFT_DIR) clean
|
|
||||||
|
|
||||||
fclean: clean
|
|
||||||
rm -f $(NAME)
|
|
||||||
rm -f $(TEST_BIN)
|
|
||||||
$(MAKE) -C $(LIBFT_DIR) fclean
|
|
||||||
|
|
||||||
re: fclean all
|
|
||||||
|
|
||||||
multi:
|
|
||||||
$(MAKE) $(LIBFT)
|
|
||||||
$(MAKE) $(NAME)
|
|
||||||
|
|
||||||
|
|
||||||
# special stuff
|
|
||||||
|
|
||||||
vpath %.c $(SRC_DIR) \
|
|
||||||
$(TST_DIR)
|
|
||||||
|
|
||||||
.PHONY: all check clean fclean re multi
|
|
19
build.sh
Executable file
19
build.sh
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
PWD=$(pwd)
|
||||||
|
OUT_DIR="$PWD/out"
|
||||||
|
RELEASE_BLD_DIR="$PWD/bld"
|
||||||
|
DEBUG_BLD_DIR="$PWD/debug_bld"
|
||||||
|
|
||||||
|
LIB="libft_malloc.dylib"
|
||||||
|
LINK="libft_malloc.so"
|
||||||
|
|
||||||
|
|
||||||
|
meson $RELEASE_BLD_DIR --prefix=$OUT_DIR --libdir=$OUT_DIR --includedir=$OUT_DIR --buildtype=release
|
||||||
|
meson $DEBUG_BLD_DIR --buildtype=debug
|
||||||
|
|
||||||
|
ninja -C $DEBUG_BLD_DIR
|
||||||
|
ninja -C $RELEASE_BLD_DIR
|
||||||
|
ninja -C $RELEASE_BLD_DIR install
|
||||||
|
|
||||||
|
ln -sf "$OUT_DIR/$LIB" "$PWD/$LINK"
|
|
@ -1,3 +1,15 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* ft_malloc.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: gtertysh <gtertysh@student.unit.ua> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2019/05/06 22:37:16 by foton #+# #+# */
|
||||||
|
/* Updated: 2019/05/06 22:40:14 by gtertysh ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#ifndef FT_MALLOC_H
|
#ifndef FT_MALLOC_H
|
||||||
# define FT_MALLOC_H
|
# define FT_MALLOC_H
|
||||||
|
|
||||||
|
@ -5,6 +17,8 @@
|
||||||
|
|
||||||
void free(void *ptr);
|
void free(void *ptr);
|
||||||
void *malloc(size_t size);
|
void *malloc(size_t size);
|
||||||
|
void *calloc(size_t count, size_t size);
|
||||||
void *realloc(void *ptr, size_t size);
|
void *realloc(void *ptr, size_t size);
|
||||||
|
void show_alloc_mem(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
57
inc/ft_malloc_internal.h
Normal file
57
inc/ft_malloc_internal.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* ft_malloc_internal.h :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: gtertysh <gtertysh@student.unit.ua> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2019/05/06 22:37:07 by foton #+# #+# */
|
||||||
|
/* Updated: 2019/05/10 20:03:15 by gtertysh ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#ifndef FT_MALLOC_INTERNAL_H
|
||||||
|
# define FT_MALLOC_INTERNAL_H
|
||||||
|
|
||||||
|
# include <stddef.h>
|
||||||
|
# include <stdint.h>
|
||||||
|
# include <pthread.h>
|
||||||
|
|
||||||
|
# define TINY 512
|
||||||
|
# define SMALL 4096
|
||||||
|
# define LARGE 4097
|
||||||
|
# define START -1
|
||||||
|
# define MAGIC 0xDEADBEEF
|
||||||
|
# define NALLOC 100
|
||||||
|
|
||||||
|
typedef struct s_chunk
|
||||||
|
{
|
||||||
|
uint8_t is_free;
|
||||||
|
size_t size;
|
||||||
|
struct s_chunk *next;
|
||||||
|
struct s_chunk *prev;
|
||||||
|
uint32_t magic;
|
||||||
|
} t_chunk;
|
||||||
|
|
||||||
|
# define CHUNK_SIZE(size) ((size) + sizeof(t_chunk))
|
||||||
|
|
||||||
|
typedef struct s_arena
|
||||||
|
{
|
||||||
|
int type;
|
||||||
|
size_t size;
|
||||||
|
struct s_arena *next;
|
||||||
|
t_chunk *heap;
|
||||||
|
} t_arena;
|
||||||
|
|
||||||
|
# define HEAP_SIZE(size) ((size) - sizeof(t_arena))
|
||||||
|
# define ARENA_SIZE(size) ((size) + sizeof(t_arena))
|
||||||
|
|
||||||
|
extern t_arena g_base;
|
||||||
|
|
||||||
|
extern pthread_mutex_t g_malloc_mutex;
|
||||||
|
|
||||||
|
int get_arena_type(size_t size);
|
||||||
|
void *malloc_core(size_t size);
|
||||||
|
void free_core(void *used);
|
||||||
|
|
||||||
|
#endif
|
|
@ -1 +0,0 @@
|
||||||
install_headers('ft_malloc.h')
|
|
51
meson.build
51
meson.build
|
@ -1,6 +1,51 @@
|
||||||
project('malloc', 'c')
|
project(
|
||||||
|
'malloc',
|
||||||
|
'c',
|
||||||
|
default_options: [
|
||||||
|
'buildtype=plain',
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
add_global_arguments(
|
||||||
|
'-O0',
|
||||||
|
'-Wall',
|
||||||
|
'-Wextra',
|
||||||
|
'-Werror',
|
||||||
|
'-Wcast-align',
|
||||||
|
'-Wwrite-strings',
|
||||||
|
'-Wunreachable-code',
|
||||||
|
'-Winit-self',
|
||||||
|
'-Wmissing-field-initializers',
|
||||||
|
'-Wno-unknown-pragmas',
|
||||||
|
'-Wstrict-prototypes',
|
||||||
|
'-Wundef',
|
||||||
|
'-Wold-style-definition',
|
||||||
|
language: 'c',
|
||||||
|
)
|
||||||
|
|
||||||
inc = include_directories('inc')
|
inc = include_directories('inc')
|
||||||
subdir('inc')
|
|
||||||
subdir('src')
|
install_headers('inc/ft_malloc.h')
|
||||||
|
|
||||||
|
sources = [
|
||||||
|
'src/malloc.c',
|
||||||
|
'src/free.c',
|
||||||
|
'src/realloc.c',
|
||||||
|
'src/calloc.c',
|
||||||
|
'src/get_arena_type.c',
|
||||||
|
'src/show_alloc_mem.c',
|
||||||
|
]
|
||||||
|
|
||||||
|
libft = subproject('libft')
|
||||||
|
|
||||||
|
libft_dep = libft.get_variable('libft_dep')
|
||||||
|
|
||||||
|
ft_malloc = shared_library(
|
||||||
|
'ft_malloc',
|
||||||
|
sources,
|
||||||
|
include_directories: inc,
|
||||||
|
dependencies: libft_dep,
|
||||||
|
install: true,
|
||||||
|
)
|
||||||
|
|
||||||
subdir('t')
|
subdir('t')
|
35
src/calloc.c
Normal file
35
src/calloc.c
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* calloc.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: gtertysh <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2019/05/08 21:07:09 by gtertysh #+# #+# */
|
||||||
|
/* Updated: 2019/05/08 21:07:34 by gtertysh ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "ft_malloc_internal.h"
|
||||||
|
#include "libft.h"
|
||||||
|
|
||||||
|
static void *calloc_core(size_t count, size_t size)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
ptr = malloc(count * size);
|
||||||
|
if (!ptr)
|
||||||
|
return (NULL);
|
||||||
|
ft_bzero(ptr, count * size);
|
||||||
|
return (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *calloc(size_t count, size_t size)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&g_malloc_mutex);
|
||||||
|
ptr = calloc_core(count, size);
|
||||||
|
pthread_mutex_unlock(&g_malloc_mutex);
|
||||||
|
return (ptr);
|
||||||
|
}
|
44
src/free.c
44
src/free.c
|
@ -1,6 +1,48 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* free.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: gtertysh <gtertysh@student.unit.ua> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2019/05/06 22:35:53 by foton #+# #+# */
|
||||||
|
/* Updated: 2019/05/08 21:08:00 by gtertysh ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "ft_malloc.h"
|
#include "ft_malloc.h"
|
||||||
|
#include "ft_malloc_internal.h"
|
||||||
|
|
||||||
|
void free_core(void *used)
|
||||||
|
{
|
||||||
|
t_chunk *chunk;
|
||||||
|
|
||||||
|
if (!used)
|
||||||
|
return ;
|
||||||
|
chunk = (t_chunk *)used - 1;
|
||||||
|
if (chunk->magic != MAGIC)
|
||||||
|
return ;
|
||||||
|
chunk->is_free = 1;
|
||||||
|
if (chunk->prev && chunk->prev->is_free)
|
||||||
|
{
|
||||||
|
chunk->prev->size += chunk->size;
|
||||||
|
chunk->prev->next = chunk->next;
|
||||||
|
if (chunk->next)
|
||||||
|
chunk->next->prev = chunk->prev;
|
||||||
|
chunk = chunk->prev;
|
||||||
|
}
|
||||||
|
if (chunk->next && chunk->next->is_free)
|
||||||
|
{
|
||||||
|
chunk->size += chunk->next->size;
|
||||||
|
chunk->next = chunk->next->next;
|
||||||
|
if (chunk->next)
|
||||||
|
chunk->next->prev = chunk;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void free(void *used)
|
void free(void *used)
|
||||||
{
|
{
|
||||||
return ;
|
pthread_mutex_lock(&g_malloc_mutex);
|
||||||
|
free_core(used);
|
||||||
|
pthread_mutex_unlock(&g_malloc_mutex);
|
||||||
}
|
}
|
||||||
|
|
22
src/get_arena_type.c
Normal file
22
src/get_arena_type.c
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* get_arena_type.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: gtertysh <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2019/05/08 21:08:05 by gtertysh #+# #+# */
|
||||||
|
/* Updated: 2019/05/08 21:08:06 by gtertysh ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "ft_malloc_internal.h"
|
||||||
|
|
||||||
|
int get_arena_type(size_t size)
|
||||||
|
{
|
||||||
|
if (size <= CHUNK_SIZE(TINY))
|
||||||
|
return (TINY);
|
||||||
|
if (size <= CHUNK_SIZE(SMALL))
|
||||||
|
return (SMALL);
|
||||||
|
return (LARGE);
|
||||||
|
}
|
114
src/malloc.c
114
src/malloc.c
|
@ -1,7 +1,117 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* malloc.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: gtertysh <gtertysh@student.unit.ua> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2019/05/06 22:35:57 by foton #+# #+# */
|
||||||
|
/* Updated: 2019/05/08 21:08:52 by gtertysh ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include <sys/mman.h>
|
||||||
#include "ft_malloc.h"
|
#include "ft_malloc.h"
|
||||||
|
#include "ft_malloc_internal.h"
|
||||||
|
#include "libft.h"
|
||||||
|
|
||||||
|
t_arena g_base = { .type = START, .size = 0, .next = &g_base, .heap = NULL};
|
||||||
|
|
||||||
|
pthread_mutex_t g_malloc_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
static size_t get_actual_size(size_t size, int type)
|
||||||
|
{
|
||||||
|
size_t minimum;
|
||||||
|
int page;
|
||||||
|
|
||||||
|
page = getpagesize();
|
||||||
|
if (type == LARGE)
|
||||||
|
minimum = size;
|
||||||
|
else
|
||||||
|
minimum = ((CHUNK_SIZE(type)) * NALLOC);
|
||||||
|
return ((ARENA_SIZE(minimum) + page - 1) / page * page);
|
||||||
|
}
|
||||||
|
|
||||||
|
static t_arena *get_more_arena(size_t size, int type)
|
||||||
|
{
|
||||||
|
t_arena *arena;
|
||||||
|
int prot;
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
size = get_actual_size(size, type);
|
||||||
|
prot = PROT_WRITE | PROT_READ;
|
||||||
|
flags = MAP_ANON | MAP_PRIVATE;
|
||||||
|
if ((arena = mmap(NULL, size, prot, flags, -1, 0)) == MAP_FAILED)
|
||||||
|
return (NULL);
|
||||||
|
arena->size = size;
|
||||||
|
arena->type = type;
|
||||||
|
arena->heap = (t_chunk *)(arena + 1);
|
||||||
|
arena->heap->is_free = 1;
|
||||||
|
arena->heap->magic = MAGIC;
|
||||||
|
arena->heap->size = HEAP_SIZE(size);
|
||||||
|
arena->heap->next = NULL;
|
||||||
|
arena->heap->prev = NULL;
|
||||||
|
arena->next = g_base.next;
|
||||||
|
g_base.next = arena;
|
||||||
|
return (arena);
|
||||||
|
}
|
||||||
|
|
||||||
|
static t_chunk *chunk_heap(t_chunk *chunk, size_t size)
|
||||||
|
{
|
||||||
|
t_chunk *new_chunk;
|
||||||
|
|
||||||
|
if (chunk->size == size || chunk->size - size < sizeof(t_chunk))
|
||||||
|
{
|
||||||
|
chunk->is_free = 0;
|
||||||
|
return (chunk);
|
||||||
|
}
|
||||||
|
chunk->size -= size;
|
||||||
|
new_chunk = (t_chunk *)((size_t)chunk + chunk->size);
|
||||||
|
new_chunk->is_free = 0;
|
||||||
|
new_chunk->magic = MAGIC;
|
||||||
|
new_chunk->size = size;
|
||||||
|
new_chunk->next = chunk->next;
|
||||||
|
new_chunk->prev = chunk;
|
||||||
|
new_chunk->prev->next = new_chunk;
|
||||||
|
if (new_chunk->next)
|
||||||
|
new_chunk->next->prev = new_chunk;
|
||||||
|
return (new_chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *malloc_core(size_t size)
|
||||||
|
{
|
||||||
|
t_arena *arena;
|
||||||
|
t_chunk *heap;
|
||||||
|
t_chunk *space;
|
||||||
|
int arena_type;
|
||||||
|
|
||||||
|
space = NULL;
|
||||||
|
size = CHUNK_SIZE(size);
|
||||||
|
arena = g_base.next;
|
||||||
|
arena_type = get_arena_type(size);
|
||||||
|
while (!space)
|
||||||
|
{
|
||||||
|
if (arena->type == arena_type && (heap = arena->heap))
|
||||||
|
while (!space && heap)
|
||||||
|
{
|
||||||
|
if (heap->size >= size && heap->is_free)
|
||||||
|
space = chunk_heap(heap, size);
|
||||||
|
heap = heap->next;
|
||||||
|
}
|
||||||
|
arena = arena->next;
|
||||||
|
if (!space && arena == &g_base)
|
||||||
|
if ((arena = get_more_arena(size, arena_type)) == NULL)
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
return (space + 1);
|
||||||
|
}
|
||||||
|
|
||||||
void *malloc(size_t size)
|
void *malloc(size_t size)
|
||||||
{
|
{
|
||||||
(void)size;
|
void *ptr;
|
||||||
return (NULL);
|
|
||||||
|
pthread_mutex_lock(&g_malloc_mutex);
|
||||||
|
ptr = malloc_core(size);
|
||||||
|
pthread_mutex_unlock(&g_malloc_mutex);
|
||||||
|
return (ptr);
|
||||||
}
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
srcs = [
|
|
||||||
'malloc.c',
|
|
||||||
'free.c',
|
|
||||||
'realloc.c',
|
|
||||||
]
|
|
||||||
|
|
||||||
ft_malloc = shared_library('ft_malloc', srcs, include_directories: inc)
|
|
|
@ -1,6 +1,43 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* realloc.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: gtertysh <gtertysh@student.unit.ua> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2019/05/06 22:35:48 by foton #+# #+# */
|
||||||
|
/* Updated: 2019/05/08 21:09:05 by gtertysh ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "ft_malloc.h"
|
#include "ft_malloc.h"
|
||||||
|
#include "ft_malloc_internal.h"
|
||||||
|
#include "libft.h"
|
||||||
|
|
||||||
|
static void *realloc_core(void *ptr, size_t size)
|
||||||
|
{
|
||||||
|
t_chunk *chunk;
|
||||||
|
t_chunk *new_chunk;
|
||||||
|
|
||||||
|
if (!ptr)
|
||||||
|
return (malloc(size));
|
||||||
|
chunk = (t_chunk *)ptr - 1;
|
||||||
|
if (chunk->magic != MAGIC)
|
||||||
|
return (NULL);
|
||||||
|
if (chunk->size >= CHUNK_SIZE(size))
|
||||||
|
return (ptr);
|
||||||
|
new_chunk = malloc_core(size);
|
||||||
|
ft_memmove(new_chunk, ptr, chunk->size - CHUNK_SIZE(0));
|
||||||
|
free_core(ptr);
|
||||||
|
return (new_chunk);
|
||||||
|
}
|
||||||
|
|
||||||
void *realloc(void *ptr, size_t size)
|
void *realloc(void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
return (NULL);
|
void *new_ptr;
|
||||||
|
|
||||||
|
pthread_mutex_lock(&g_malloc_mutex);
|
||||||
|
new_ptr = realloc_core(ptr, size);
|
||||||
|
pthread_mutex_unlock(&g_malloc_mutex);
|
||||||
|
return (new_ptr);
|
||||||
}
|
}
|
85
src/show_alloc_mem.c
Normal file
85
src/show_alloc_mem.c
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* show_alloc_mem.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: gtertysh <gtertysh@student.unit.ua> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2019/05/08 21:45:17 by gtertysh #+# #+# */
|
||||||
|
/* Updated: 2019/05/09 23:46:34 by gtertysh ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
#include "ft_malloc_internal.h"
|
||||||
|
#include "ft_malloc.h"
|
||||||
|
#include "libft.h"
|
||||||
|
#include "stdio.h"
|
||||||
|
|
||||||
|
static void print_addr(void *addr)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
size_t bit_4;
|
||||||
|
size_t count;
|
||||||
|
|
||||||
|
count = sizeof(addr) * 2;
|
||||||
|
i = 0;
|
||||||
|
while (i < count)
|
||||||
|
{
|
||||||
|
bit_4 = ((size_t)addr >> ((count - i - 1) * 4)) & 0xf;
|
||||||
|
if (bit_4 < 10)
|
||||||
|
ft_putnbr(bit_4);
|
||||||
|
else
|
||||||
|
ft_putchar('A' + bit_4 - 10);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_size(void *addr, size_t size)
|
||||||
|
{
|
||||||
|
print_addr(addr + size);
|
||||||
|
ft_putstr(" - ");
|
||||||
|
print_addr(addr);
|
||||||
|
ft_putstr(" : size ");
|
||||||
|
ft_putnbr(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_arena(t_arena *arena)
|
||||||
|
{
|
||||||
|
if (arena->type == TINY)
|
||||||
|
ft_putstr("TINY : ");
|
||||||
|
else if (arena->type == SMALL)
|
||||||
|
ft_putstr("SMALL : ");
|
||||||
|
else
|
||||||
|
ft_putstr("LARGE : ");
|
||||||
|
print_size(arena, arena->size);
|
||||||
|
ft_putstr(" of ARENA\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_chunk(t_chunk *chunk)
|
||||||
|
{
|
||||||
|
ft_putstr(" ");
|
||||||
|
print_size(chunk, chunk->size);
|
||||||
|
if (chunk->is_free)
|
||||||
|
ft_putstr(" of free block\n");
|
||||||
|
else
|
||||||
|
ft_putstr(" of not free block\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void show_alloc_mem(void)
|
||||||
|
{
|
||||||
|
t_arena *arena_runner;
|
||||||
|
t_chunk *heap_runner;
|
||||||
|
|
||||||
|
arena_runner = g_base.next;
|
||||||
|
while (arena_runner != &g_base)
|
||||||
|
{
|
||||||
|
heap_runner = arena_runner->heap;
|
||||||
|
print_arena(arena_runner);
|
||||||
|
while (heap_runner)
|
||||||
|
{
|
||||||
|
print_chunk(heap_runner);
|
||||||
|
heap_runner = heap_runner->next;
|
||||||
|
}
|
||||||
|
arena_runner = arena_runner->next;
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
#include "libft.h"
|
#include "libft.h"
|
||||||
|
|
||||||
static t_list *merge(t_list *a, t_list *b, int (*cmp)())
|
static t_list *merge(t_list *a, t_list *b, int (*cmp)(void *, void *))
|
||||||
{
|
{
|
||||||
t_list *result;
|
t_list *result;
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ static void split(t_list *source, t_list **front_ptr, t_list **back_ptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ft_lst_merge_sort(t_list **head_ptr, int (*cmp)())
|
void ft_lst_merge_sort(t_list **head_ptr, int (*cmp)(void *, void *))
|
||||||
{
|
{
|
||||||
t_list *head;
|
t_list *head;
|
||||||
t_list *a;
|
t_list *a;
|
|
@ -14,5 +14,6 @@
|
||||||
|
|
||||||
void ft_putchar(char c)
|
void ft_putchar(char c)
|
||||||
{
|
{
|
||||||
write(1, &c, 1);
|
if (write(1, &c, 1) == -1)
|
||||||
|
return ;
|
||||||
}
|
}
|
|
@ -14,5 +14,6 @@
|
||||||
|
|
||||||
void ft_putchar_fd(char c, int fd)
|
void ft_putchar_fd(char c, int fd)
|
||||||
{
|
{
|
||||||
write(fd, &c, 1);
|
if (write(fd, &c, 1) == -1)
|
||||||
|
return ;
|
||||||
}
|
}
|
|
@ -16,6 +16,8 @@ void ft_putendl(char const *s)
|
||||||
{
|
{
|
||||||
if (s)
|
if (s)
|
||||||
while (*s)
|
while (*s)
|
||||||
write(1, s++, 1);
|
if (write(1, s++, 1) == -1)
|
||||||
write(1, "\n", 1);
|
return ;
|
||||||
|
if (write(1, "\n", 1) == -1)
|
||||||
|
return ;
|
||||||
}
|
}
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: gtertysh <marvin@42.fr> +#+ +:+ +#+ */
|
/* By: gtertysh <marvin@42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2016/12/04 15:17:18 by gtertysh #+# #+# */
|
/* Created: 2016/12/04 15:17:18 by gtertysh #+# #+# */
|
||||||
/* Updated: 2016/12/04 15:24:55 by gtertysh ### ########.fr */
|
/* Updated: 2019/05/08 19:48:54 by gtertysh ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ void ft_putendl_fd(char const *s, int fd)
|
||||||
{
|
{
|
||||||
if (s)
|
if (s)
|
||||||
while (*s)
|
while (*s)
|
||||||
write(fd, s++, 1);
|
if (write(fd, s++, 1) == -1)
|
||||||
write(fd, "\n", 1);
|
return ;
|
||||||
|
if (write(fd, "\n", 1) == -1)
|
||||||
|
return ;
|
||||||
}
|
}
|
|
@ -16,5 +16,6 @@ void ft_putstr(char const *s)
|
||||||
{
|
{
|
||||||
if (s)
|
if (s)
|
||||||
while (*s)
|
while (*s)
|
||||||
write(1, s++, 1);
|
if (write(1, s++, 1) == -1)
|
||||||
|
return ;
|
||||||
}
|
}
|
|
@ -16,5 +16,6 @@ void ft_putstr_fd(char const *s, int fd)
|
||||||
{
|
{
|
||||||
if (s)
|
if (s)
|
||||||
while (*s)
|
while (*s)
|
||||||
write(fd, s++, 1);
|
if (write(fd, s++, 1) == -1)
|
||||||
|
return ;
|
||||||
}
|
}
|
94
subprojects/libft/meson.build
Normal file
94
subprojects/libft/meson.build
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
project('libft', 'c')
|
||||||
|
|
||||||
|
srcs = [
|
||||||
|
'ft_memset.c',
|
||||||
|
'ft_bzero.c',
|
||||||
|
'ft_memcpy.c',
|
||||||
|
'ft_memccpy.c',
|
||||||
|
'ft_memmove.c',
|
||||||
|
'ft_memchr.c',
|
||||||
|
'ft_memcmp.c',
|
||||||
|
'ft_strlen.c',
|
||||||
|
'ft_strdup.c',
|
||||||
|
'ft_strcpy.c',
|
||||||
|
'ft_strncpy.c',
|
||||||
|
'ft_strcat.c',
|
||||||
|
'ft_strncat.c',
|
||||||
|
'ft_strlcat.c',
|
||||||
|
'ft_strchr.c',
|
||||||
|
'ft_strrchr.c',
|
||||||
|
'ft_strstr.c',
|
||||||
|
'ft_strnstr.c',
|
||||||
|
'ft_strcmp.c',
|
||||||
|
'ft_strcmp_lex.c',
|
||||||
|
'ft_strncmp.c',
|
||||||
|
'ft_strtol.c',
|
||||||
|
'ft_atoi.c',
|
||||||
|
'ft_atof.c',
|
||||||
|
'ft_isalpha.c',
|
||||||
|
'ft_isspace.c',
|
||||||
|
'ft_isdigit.c',
|
||||||
|
'ft_isalnum.c',
|
||||||
|
'ft_isascii.c',
|
||||||
|
'ft_isprint.c',
|
||||||
|
'ft_toupper.c',
|
||||||
|
'ft_tolower.c',
|
||||||
|
'ft_memalloc.c',
|
||||||
|
'ft_memdel.c',
|
||||||
|
'ft_strnew.c',
|
||||||
|
'ft_strdel.c',
|
||||||
|
'ft_strclr.c',
|
||||||
|
'ft_striter.c',
|
||||||
|
'ft_striteri.c',
|
||||||
|
'ft_strmap.c',
|
||||||
|
'ft_strmap.c',
|
||||||
|
'ft_strmapi.c',
|
||||||
|
'ft_strequ.c',
|
||||||
|
'ft_strnequ.c',
|
||||||
|
'ft_strsub.c',
|
||||||
|
'ft_strjoin.c',
|
||||||
|
'ft_strtrim.c',
|
||||||
|
'ft_strsplit.c',
|
||||||
|
'ft_itoa.c',
|
||||||
|
'ft_putchar.c',
|
||||||
|
'ft_putstr.c',
|
||||||
|
'ft_putendl.c',
|
||||||
|
'ft_putnbr.c',
|
||||||
|
'ft_putchar_fd.c',
|
||||||
|
'ft_putstr_fd.c',
|
||||||
|
'ft_putendl_fd.c',
|
||||||
|
'ft_putnbr_fd.c',
|
||||||
|
'ft_lstnew.c',
|
||||||
|
'ft_lstdelone.c',
|
||||||
|
'ft_lstdel.c',
|
||||||
|
'ft_lstadd.c',
|
||||||
|
'ft_lstiter.c',
|
||||||
|
'ft_lstmap.c',
|
||||||
|
'ft_lstreduce.c',
|
||||||
|
'ft_lststrsplit.c',
|
||||||
|
'ft_lstfind.c',
|
||||||
|
'ft_lst_at.c',
|
||||||
|
'ft_lstadd_back.c',
|
||||||
|
'ft_lst_len.c',
|
||||||
|
'ft_lst_merge_sort.c',
|
||||||
|
'ft_lst_rev.c',
|
||||||
|
'ft_lst_search.c',
|
||||||
|
'ft_realloc.c',
|
||||||
|
'ft_read_file.c',
|
||||||
|
'get_next_line.c',
|
||||||
|
'ft_num_len.c',
|
||||||
|
'ft_str_table_len.c',
|
||||||
|
]
|
||||||
|
|
||||||
|
inc = include_directories('includes')
|
||||||
|
|
||||||
|
libft = static_library(
|
||||||
|
'ft',
|
||||||
|
srcs,
|
||||||
|
include_directories: inc,
|
||||||
|
)
|
||||||
|
|
||||||
|
libft_dep = declare_dependency(
|
||||||
|
include_directories : inc,
|
||||||
|
link_with : libft,
|
||||||
|
)
|
108
t/fuzzy.c
Normal file
108
t/fuzzy.c
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
struct item {
|
||||||
|
void *ptr;
|
||||||
|
size_t size;
|
||||||
|
size_t hash;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void hash_compute(struct item *item) {
|
||||||
|
unsigned char c;
|
||||||
|
size_t hash = 0xdeadbeef;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < item->size; i++) {
|
||||||
|
c = rand();
|
||||||
|
((unsigned char *)item->ptr)[i] = c;
|
||||||
|
hash += (hash << 13) ^ c;
|
||||||
|
hash ^= (hash << 26) - (c * ((hash >> 56) + 1));
|
||||||
|
}
|
||||||
|
item->hash = hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hash_check(struct item *item) {
|
||||||
|
unsigned char c;
|
||||||
|
size_t hash = 0xdeadbeef;
|
||||||
|
|
||||||
|
if (item->ptr == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < item->size; i++) {
|
||||||
|
c = ((unsigned char *)item->ptr)[i];
|
||||||
|
hash += (hash << 13) ^ c;
|
||||||
|
hash ^= (hash << 26) - (c * ((hash >> 56) + 1));
|
||||||
|
}
|
||||||
|
return (item->hash == hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char *const argv[]) {
|
||||||
|
if (argc < 4) {
|
||||||
|
puts("Usage: ... num_passes num_items size_min size_max");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t num_passes = atoi(argv[1]),
|
||||||
|
num_items = atoi(argv[2]),
|
||||||
|
size_min = atoi(argv[3]),
|
||||||
|
size_max = atoi(argv[4]);
|
||||||
|
struct item items[num_items];
|
||||||
|
|
||||||
|
srand(argc + num_items + size_min + size_max);
|
||||||
|
srand(rand() ^ time(NULL));
|
||||||
|
bzero(items, sizeof(struct item) * num_items);
|
||||||
|
|
||||||
|
for (size_t pass = 0; pass < num_passes; pass++) {
|
||||||
|
for (size_t i = 0; i < num_items; i++) {
|
||||||
|
if (pass % 3 == 0) {
|
||||||
|
if (rand() & 1 && items[i].ptr == NULL) {
|
||||||
|
items[i].size = rand() % (size_max - size_min) + size_min;
|
||||||
|
items[i].ptr = malloc(items[i].size);
|
||||||
|
if (items[i].ptr) {
|
||||||
|
hash_compute(&items[i]);
|
||||||
|
printf("pass %-2lu item %-4lu malloc(%lu) => %p..%p\n",
|
||||||
|
pass, i, items[i].size, items[i].ptr, items[i].ptr + items[i].size);
|
||||||
|
} else {
|
||||||
|
printf("\033[0;31mpass %-2lu item %-4lu returned NULL\033[0m\n", pass, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (pass % 3 == 1) {
|
||||||
|
if (rand() & 1 && items[i].ptr != NULL) {
|
||||||
|
void *old_ptr = items[i].ptr;
|
||||||
|
items[i].size = rand() % (size_max - size_min) + size_min;
|
||||||
|
items[i].ptr = realloc(items[i].ptr, items[i].size);
|
||||||
|
if (items[i].ptr) {
|
||||||
|
hash_compute(&items[i]);
|
||||||
|
printf("pass %-2lu item %-4lu realloc(%p, %lu) => %p\n",
|
||||||
|
pass, i, old_ptr, items[i].size, items[i].ptr);
|
||||||
|
} else {
|
||||||
|
printf("\033[0;31mpass %-2lu item %-4lu realloc failed\033[0m\n", pass, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (rand() & 1 && items[i].ptr != NULL) {
|
||||||
|
printf("pass %-2lu item %-4lu free(%p)\n",
|
||||||
|
pass, i, items[i].ptr);
|
||||||
|
free(items[i].ptr);
|
||||||
|
items[i].ptr = NULL;
|
||||||
|
} else if (pass == num_passes - 1 && items[i].ptr != NULL) {
|
||||||
|
printf("pass %-2lu item %-4lu free(%p)\n",
|
||||||
|
pass, i, items[i].ptr);
|
||||||
|
free(items[i].ptr);
|
||||||
|
items[i].ptr = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t j = 0; j < num_items; j++) {
|
||||||
|
if (!hash_check(&items[i])) {
|
||||||
|
printf("\033[0;31mpass %-2lu item %-4lu hash_check failed\033[0m\n", pass, i);
|
||||||
|
items[i].ptr = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* show_alloc_mem(); */
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
115
t/fuzzy_fast.c
Normal file
115
t/fuzzy_fast.c
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
// gcc -O2 -o main main.c -lz
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
#include "ft_malloc.h"
|
||||||
|
|
||||||
|
struct item {
|
||||||
|
void *ptr;
|
||||||
|
size_t size;
|
||||||
|
size_t hash;
|
||||||
|
};
|
||||||
|
|
||||||
|
int dev_urandom_fd = -1;
|
||||||
|
|
||||||
|
static void hash_compute(struct item *item) {
|
||||||
|
unsigned long pos = 0;
|
||||||
|
do {
|
||||||
|
pos += read(dev_urandom_fd, item->ptr, item->size - pos);
|
||||||
|
assert(errno == 0);
|
||||||
|
// fprintf(stderr, "Read %lu bytes from /dev/urandom\n", pos);
|
||||||
|
} while (pos < item->size);
|
||||||
|
|
||||||
|
item->hash = adler32(0, item->ptr, item->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hash_check(struct item *item) {
|
||||||
|
if (item->ptr == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return (item->hash == adler32(0, item->ptr, item->size));
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char *const argv[]) {
|
||||||
|
if (argc < 4) {
|
||||||
|
puts("Usage: ... num_passes num_items size_min size_max");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_urandom_fd = open("/dev/urandom", O_RDONLY);
|
||||||
|
assert(dev_urandom_fd >= 0);
|
||||||
|
|
||||||
|
size_t num_passes = atoi(argv[1]),
|
||||||
|
num_items = atoi(argv[2]),
|
||||||
|
size_min = atoi(argv[3]),
|
||||||
|
size_max = atoi(argv[4]);
|
||||||
|
struct item items[num_items];
|
||||||
|
|
||||||
|
srand(argc + num_items + size_min + size_max + (int)(long)argv[0]);
|
||||||
|
srand(rand() ^ time(NULL));
|
||||||
|
bzero(items, sizeof(struct item) * num_items);
|
||||||
|
|
||||||
|
for (size_t pass = 0; pass < num_passes; pass++) {
|
||||||
|
for (size_t i = 0; i < num_items; i++) {
|
||||||
|
if (pass % 3 == 0) {
|
||||||
|
if (rand() & 1 && items[i].ptr == NULL) {
|
||||||
|
items[i].size = rand() % (size_max - size_min) + size_min;
|
||||||
|
items[i].ptr = malloc(items[i].size);
|
||||||
|
if (items[i].ptr) {
|
||||||
|
hash_compute(&items[i]);
|
||||||
|
printf("pass %-2lu item %-4lu malloc(%lu) => %p..%p\n",
|
||||||
|
pass, i, items[i].size, items[i].ptr, items[i].ptr + items[i].size);
|
||||||
|
} else {
|
||||||
|
printf("\033[0;31mpass %-2lu item %-4lu returned NULL\033[0m\n", pass, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (pass % 3 == 1) {
|
||||||
|
if (rand() & 1 && items[i].ptr != NULL) {
|
||||||
|
void *old_ptr = items[i].ptr;
|
||||||
|
items[i].size = rand() % (size_max - size_min) + size_min;
|
||||||
|
items[i].ptr = realloc(items[i].ptr, items[i].size);
|
||||||
|
if (items[i].ptr) {
|
||||||
|
hash_compute(&items[i]);
|
||||||
|
printf("pass %-2lu item %-4lu realloc(%p, %lu) => %p\n",
|
||||||
|
pass, i, old_ptr, items[i].size, items[i].ptr);
|
||||||
|
} else {
|
||||||
|
printf("\033[0;31mpass %-2lu item %-4lu realloc failed\033[0m\n", pass, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (rand() & 1 && items[i].ptr != NULL) {
|
||||||
|
printf("pass %-2lu item %-4lu free(%p)\n",
|
||||||
|
pass, i, items[i].ptr);
|
||||||
|
free(items[i].ptr);
|
||||||
|
items[i].ptr = NULL;
|
||||||
|
} else if (pass == num_passes - 1 && items[i].ptr != NULL) {
|
||||||
|
printf("pass %-2lu item %-4lu free(%p)\n",
|
||||||
|
pass, i, items[i].ptr);
|
||||||
|
free(items[i].ptr);
|
||||||
|
items[i].ptr = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t j = 0; j < num_items; j++) {
|
||||||
|
if (!hash_check(&items[i])) {
|
||||||
|
printf("\033[0;31mpass %-2lu item %-4lu hash_check failed\033[0m\n", pass, i);
|
||||||
|
items[i].ptr = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
show_alloc_mem();
|
||||||
|
}
|
||||||
|
|
||||||
|
close(dev_urandom_fd);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
115
t/malloc_tests.c
115
t/malloc_tests.c
|
@ -1,13 +1,116 @@
|
||||||
#include "t.h"
|
/* ************************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* ::: :::::::: */
|
||||||
|
/* malloc_tests.c :+: :+: :+: */
|
||||||
|
/* +:+ +:+ +:+ */
|
||||||
|
/* By: gtertysh <gtertysh@student.unit.ua> +#+ +:+ +#+ */
|
||||||
|
/* +#+#+#+#+#+ +#+ */
|
||||||
|
/* Created: 2019/05/06 22:35:37 by foton #+# #+# */
|
||||||
|
/* Updated: 2019/05/09 23:49:52 by gtertysh ### ########.fr */
|
||||||
|
/* */
|
||||||
|
/* ************************************************************************** */
|
||||||
|
|
||||||
int return_null_on_zero_size()
|
#include <unistd.h>
|
||||||
|
#include "t.h"
|
||||||
|
#include "ft_malloc.h"
|
||||||
|
#include "ft_malloc_internal.h"
|
||||||
|
|
||||||
|
int inital_base_next_point_to_itself(void)
|
||||||
{
|
{
|
||||||
_IS(1 == 1);
|
_IS(g_base.next == &g_base);
|
||||||
_END("return null on zero size");
|
_END("inital_base_next_point_to_itself");
|
||||||
|
}
|
||||||
|
|
||||||
|
int returns_not_null_pointer(void)
|
||||||
|
{
|
||||||
|
t_chunk *ptr;
|
||||||
|
|
||||||
|
g_base.next = &g_base;
|
||||||
|
ptr = malloc(10);
|
||||||
|
_IS(ptr != NULL);
|
||||||
|
ptr = ptr - 1;
|
||||||
|
_IS(ptr->is_free == 0);
|
||||||
|
_IS(ptr->size == 10 + sizeof(t_chunk));
|
||||||
|
_IS(ptr->magic == MAGIC);
|
||||||
|
_IS(ptr->next == NULL);
|
||||||
|
_IS(ptr->prev != NULL);
|
||||||
|
_IS(ptr->prev->size > TINY * NALLOC && ptr->prev->size < SMALL * NALLOC);
|
||||||
|
// show_alloc_mem();
|
||||||
|
_END("returns_not_null_pointer");
|
||||||
|
}
|
||||||
|
|
||||||
|
int free_concatenates_adjacent_blocks(void)
|
||||||
|
{
|
||||||
|
t_chunk *ptr;
|
||||||
|
t_chunk *next_malloc;
|
||||||
|
t_chunk *heap;
|
||||||
|
|
||||||
|
g_base.next = &g_base;
|
||||||
|
ptr = malloc(10);
|
||||||
|
next_malloc = malloc(10);
|
||||||
|
ptr -= 1;
|
||||||
|
next_malloc -= 1;
|
||||||
|
free(ptr + 1);
|
||||||
|
_IS(ptr->is_free == 1);
|
||||||
|
_IS(ptr->prev == next_malloc);
|
||||||
|
_IS(next_malloc->is_free == 0);
|
||||||
|
_IS(next_malloc->next == ptr);
|
||||||
|
_IS(next_malloc->prev->prev == NULL);
|
||||||
|
heap = next_malloc->prev;
|
||||||
|
free(next_malloc + 1);
|
||||||
|
_IS(heap->is_free == 1);
|
||||||
|
_IS(heap->prev == NULL);
|
||||||
|
_IS(heap->next == NULL);
|
||||||
|
_END("free_concatenates_adjacent_blocks");
|
||||||
|
}
|
||||||
|
|
||||||
|
int malloc_creates_new_arena(void)
|
||||||
|
{
|
||||||
|
t_chunk *second_arena_chunk;
|
||||||
|
int chunks_count;
|
||||||
|
int i;
|
||||||
|
int page;
|
||||||
|
|
||||||
|
g_base.next = &g_base;
|
||||||
|
page = getpagesize();
|
||||||
|
// minimum 100 chunks aligned to page size
|
||||||
|
chunks_count = (ARENA_SIZE(CHUNK_SIZE(TINY) * NALLOC) + page - 1)
|
||||||
|
/ page * page / CHUNK_SIZE(TINY);
|
||||||
|
i = 0;
|
||||||
|
while (i < chunks_count)
|
||||||
|
{
|
||||||
|
second_arena_chunk = malloc(TINY);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
_IS(g_base.next->next == &g_base);
|
||||||
|
_IS(g_base.next->type == TINY);
|
||||||
|
second_arena_chunk = malloc(TINY);
|
||||||
|
_IS(g_base.next->next != &g_base);
|
||||||
|
_IS(g_base.next->type == TINY);
|
||||||
|
_IS(g_base.next->heap->next == second_arena_chunk - 1);
|
||||||
|
// show_alloc_mem();
|
||||||
|
_END("malloc_creates_new_arena");
|
||||||
|
}
|
||||||
|
|
||||||
|
int realloc_return_same_pointer(void)
|
||||||
|
{
|
||||||
|
t_chunk *ptr;
|
||||||
|
t_chunk *new_ptr;
|
||||||
|
|
||||||
|
g_base.next = &g_base;
|
||||||
|
ptr = malloc(20000);
|
||||||
|
new_ptr = realloc(ptr, 100);
|
||||||
|
_IS(ptr == new_ptr);
|
||||||
|
// show_alloc_mem();
|
||||||
|
_END("realloc_return_same_pointer");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
_SHOULD(return_null_on_zero_size);
|
_SHOULD(inital_base_next_point_to_itself);
|
||||||
return 0;
|
_SHOULD(returns_not_null_pointer);
|
||||||
|
_SHOULD(free_concatenates_adjacent_blocks);
|
||||||
|
_SHOULD(malloc_creates_new_arena);
|
||||||
|
_SHOULD(realloc_return_same_pointer);
|
||||||
|
return (0);
|
||||||
}
|
}
|
|
@ -5,4 +5,26 @@ malloc_tests = executable(
|
||||||
link_with: ft_malloc,
|
link_with: ft_malloc,
|
||||||
)
|
)
|
||||||
|
|
||||||
test('malloc tests', malloc_tests)
|
|
||||||
|
malloc_fuzzy = executable(
|
||||||
|
'malloc_fuzzy',
|
||||||
|
'fuzzy.c',
|
||||||
|
include_directories: inc,
|
||||||
|
link_with: ft_malloc,
|
||||||
|
)
|
||||||
|
|
||||||
|
zlib_dep = dependency('zlib')
|
||||||
|
|
||||||
|
malloc_fuzzy_fast = executable(
|
||||||
|
'malloc_fuzzy_fast',
|
||||||
|
'fuzzy_fast.c',
|
||||||
|
include_directories: inc,
|
||||||
|
link_with: ft_malloc,
|
||||||
|
dependencies: zlib_dep
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
test('basic', malloc_tests)
|
||||||
|
|
||||||
|
test('fuzzy', malloc_fuzzy, args: ['10', '1000', '0', '10000'])
|
||||||
|
test('fuzzy_fast', malloc_fuzzy_fast, args: ['10', '1000', '0', '10000'])
|
Loading…
Reference in a new issue