add therad support
This commit is contained in:
parent
80fedbeb03
commit
3fa3ff5304
10 changed files with 248 additions and 34 deletions
|
@ -17,6 +17,7 @@
|
|||
|
||||
void free(void *ptr);
|
||||
void *malloc(size_t size);
|
||||
void *calloc(size_t count, size_t size);
|
||||
void *realloc(void *ptr, size_t size);
|
||||
void show_alloc_mem(void);
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
# include <stddef.h>
|
||||
# include <stdint.h>
|
||||
# include <pthread.h>
|
||||
|
||||
|
||||
# define TINY 512
|
||||
# define SMALL 4096
|
||||
|
@ -23,28 +25,34 @@
|
|||
# define MAGIC 0xDEADBEEF
|
||||
# define NALLOC 100
|
||||
|
||||
typedef struct s_chunk
|
||||
typedef struct s_chunk
|
||||
{
|
||||
uint8_t is_free;
|
||||
size_t size;
|
||||
struct s_chunk *next;
|
||||
struct s_chunk *prev;
|
||||
uint32_t magic;
|
||||
} t_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
|
||||
typedef struct s_arena
|
||||
{
|
||||
int type;
|
||||
size_t size;
|
||||
struct s_arena *next;
|
||||
t_chunk *heap;
|
||||
} t_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 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
|
||||
|
|
|
@ -7,6 +7,7 @@ project(
|
|||
)
|
||||
|
||||
add_global_arguments(
|
||||
'-O0',
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Werror',
|
||||
|
@ -30,6 +31,7 @@ sources = [
|
|||
'src/malloc.c',
|
||||
'src/free.c',
|
||||
'src/realloc.c',
|
||||
'src/get_arena_type.c'
|
||||
]
|
||||
|
||||
libft = subproject('libft')
|
||||
|
|
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);
|
||||
}
|
11
src/free.c
11
src/free.c
|
@ -6,14 +6,14 @@
|
|||
/* By: gtertysh <gtertysh@student.unit.ua> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2019/05/06 22:35:53 by foton #+# #+# */
|
||||
/* Updated: 2019/05/06 22:40:09 by gtertysh ### ########.fr */
|
||||
/* Updated: 2019/05/08 21:08:00 by gtertysh ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "ft_malloc.h"
|
||||
#include "ft_malloc_internal.h"
|
||||
|
||||
void free(void *used)
|
||||
void free_core(void *used)
|
||||
{
|
||||
t_chunk *chunk;
|
||||
|
||||
|
@ -39,3 +39,10 @@ void free(void *used)
|
|||
chunk->next->prev = chunk;
|
||||
}
|
||||
}
|
||||
|
||||
void free(void *used)
|
||||
{
|
||||
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);
|
||||
}
|
25
src/malloc.c
25
src/malloc.c
|
@ -6,7 +6,7 @@
|
|||
/* By: gtertysh <gtertysh@student.unit.ua> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2019/05/06 22:35:57 by foton #+# #+# */
|
||||
/* Updated: 2019/05/08 19:44:07 by gtertysh ### ########.fr */
|
||||
/* Updated: 2019/05/08 21:08:52 by gtertysh ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
@ -17,6 +17,8 @@
|
|||
|
||||
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;
|
||||
|
@ -30,15 +32,6 @@ static size_t get_actual_size(size_t size, int type)
|
|||
return ((ARENA_SIZE(minimum) + page - 1) / page * page);
|
||||
}
|
||||
|
||||
static int get_arena_type(size_t size)
|
||||
{
|
||||
if (size <= CHUNK_SIZE(TINY))
|
||||
return (TINY);
|
||||
if (size <= CHUNK_SIZE(SMALL))
|
||||
return (SMALL);
|
||||
return (LARGE);
|
||||
}
|
||||
|
||||
static t_arena *get_more_arena(size_t size, int type)
|
||||
{
|
||||
t_arena *arena;
|
||||
|
@ -85,7 +78,7 @@ static t_chunk *chunk_heap(t_chunk *chunk, size_t size)
|
|||
return (new_chunk);
|
||||
}
|
||||
|
||||
void *malloc(size_t size)
|
||||
void *malloc_core(size_t size)
|
||||
{
|
||||
t_arena *arena;
|
||||
t_chunk *heap;
|
||||
|
@ -112,3 +105,13 @@ void *malloc(size_t size)
|
|||
}
|
||||
return (space + 1);
|
||||
}
|
||||
|
||||
void *malloc(size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
pthread_mutex_lock(&g_malloc_mutex);
|
||||
ptr = malloc_core(size);
|
||||
pthread_mutex_unlock(&g_malloc_mutex);
|
||||
return (ptr);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/* By: gtertysh <gtertysh@student.unit.ua> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2019/05/06 22:35:48 by foton #+# #+# */
|
||||
/* Updated: 2019/05/08 19:44:41 by gtertysh ### ########.fr */
|
||||
/* Updated: 2019/05/08 21:09:05 by gtertysh ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
|||
#include "ft_malloc_internal.h"
|
||||
#include "libft.h"
|
||||
|
||||
void *realloc(void *ptr, size_t size)
|
||||
static void *realloc_core(void *ptr, size_t size)
|
||||
{
|
||||
t_chunk *chunk;
|
||||
t_chunk *new_chunk;
|
||||
|
@ -26,8 +26,18 @@ void *realloc(void *ptr, size_t size)
|
|||
return (NULL);
|
||||
if (chunk->size >= CHUNK_SIZE(size))
|
||||
return (ptr);
|
||||
new_chunk = malloc(size);
|
||||
new_chunk = malloc_core(size);
|
||||
ft_memmove(new_chunk, ptr, chunk->size - CHUNK_SIZE(0));
|
||||
free(ptr);
|
||||
free_core(ptr);
|
||||
return (new_chunk);
|
||||
}
|
||||
|
||||
void *realloc(void *ptr, size_t size)
|
||||
{
|
||||
void *new_ptr;
|
||||
|
||||
pthread_mutex_lock(&g_malloc_mutex);
|
||||
new_ptr = realloc_core(ptr, size);
|
||||
pthread_mutex_unlock(&g_malloc_mutex);
|
||||
return (new_ptr);
|
||||
}
|
||||
|
|
114
t/fuzzy_fast.c
Normal file
114
t/fuzzy_fast.c
Normal file
|
@ -0,0 +1,114 @@
|
|||
// 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>
|
||||
|
||||
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);
|
||||
}
|
|
@ -6,13 +6,25 @@ malloc_tests = executable(
|
|||
)
|
||||
|
||||
|
||||
malloc_fuzzy_tests = executable(
|
||||
malloc_fuzzy = executable(
|
||||
'malloc_fuzzy',
|
||||
'fuzzy.c',
|
||||
include_directories: inc,
|
||||
link_with: ft_malloc,
|
||||
)
|
||||
|
||||
test('malloc tests', malloc_tests)
|
||||
zlib_dep = dependency('zlib')
|
||||
|
||||
test('malloc fuzzy tests', malloc_fuzzy_tests, args: ['10', '1000', '0', '10000'])
|
||||
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: ['100', '1000', '0', '10000'])
|
Loading…
Reference in a new issue