Compare commits
10 Commits
9c4ca0c5a6
...
5ebe1346ac
Author | SHA1 | Date | |
---|---|---|---|
5ebe1346ac | |||
c7e205c8e5 | |||
253d037344 | |||
46f485dc27 | |||
61b1a16725 | |||
2bf10504d5 | |||
d6d805c2ed | |||
b11980eeca | |||
6738b0f5bb | |||
36cec79e81 |
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define DEBUG
|
|
||||||
|
|
||||||
void ft_free(void *ptr);
|
void ft_free(void *ptr);
|
||||||
void *ft_malloc(size_t size);
|
void *ft_malloc(size_t size);
|
||||||
void *ft_realloc(void *ptr, size_t size);
|
void *ft_realloc(void *ptr, size_t size);
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "align.h"
|
#include "align.h"
|
||||||
#include "chunk.h"
|
#include "chunk.h"
|
||||||
#include "chunk_manager.h"
|
#include "chunk_manager.h"
|
||||||
|
#include "malloc.h"
|
||||||
|
|
||||||
int add_new_block(chunk_t* chunk, size_t size, void *prev, bool is_used)
|
int add_new_block(chunk_t* chunk, size_t size, void *prev, bool is_used)
|
||||||
{
|
{
|
||||||
@ -19,7 +20,7 @@ int add_new_block(chunk_t* chunk, size_t size, void *prev, bool is_used)
|
|||||||
// TODO check with getrlimit()
|
// TODO check with getrlimit()
|
||||||
|
|
||||||
new_block = mmap(NULL, size + ALIGN_MARGING + HEADER_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
new_block = mmap(NULL, size + ALIGN_MARGING + HEADER_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
#ifndef DEBUG
|
#ifdef DEBUG
|
||||||
if (new_block == NULL)
|
if (new_block == NULL)
|
||||||
write(2, "mmap failed\n", 12);
|
write(2, "mmap failed\n", 12);
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,14 +3,15 @@
|
|||||||
#include "raw_chunk_manager.h"
|
#include "raw_chunk_manager.h"
|
||||||
#include "print.h"
|
#include "print.h"
|
||||||
#include "block.h"
|
#include "block.h"
|
||||||
|
#include "malloc.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
void chunk_merge(chunk_t *first, chunk_t *second)
|
void chunk_merge(chunk_t *first, chunk_t *second)
|
||||||
{
|
{
|
||||||
#ifndef DEBUG
|
#ifdef DEBUG
|
||||||
if (first->block_id != second->block_id)
|
if (first->block_id != second->block_id)
|
||||||
putstr("Attempt merge two chunk on different block\n");
|
write(2, "Attempt merge two chunk on different block\n", 43);
|
||||||
#endif
|
#endif
|
||||||
first->size = second->data_start - first->data_start + second->size;
|
first->size = second->data_start - first->data_start + second->size;
|
||||||
first->next = second->next;
|
first->next = second->next;
|
||||||
@ -22,8 +23,7 @@ int chunk_split(chunk_t *chunk, size_t new_size)
|
|||||||
{
|
{
|
||||||
chunk_t new_chunk;
|
chunk_t new_chunk;
|
||||||
|
|
||||||
#ifndef DEBUG
|
#ifdef DEBUG
|
||||||
// NOT ENOUGH SIZE TO BE SPLITTED
|
|
||||||
if (chunk->size + 1 < new_size + HEADER_SIZE + get_align_increment(chunk->current + HEADER_SIZE))
|
if (chunk->size + 1 < new_size + HEADER_SIZE + get_align_increment(chunk->current + HEADER_SIZE))
|
||||||
write(2, "chunk too small to be splitted\n", 31);
|
write(2, "chunk too small to be splitted\n", 31);
|
||||||
#endif
|
#endif
|
||||||
@ -60,4 +60,24 @@ int get_append_unused_chunk(void *root, size_t size, chunk_t *result, size_t new
|
|||||||
chunk_split(result, size);
|
chunk_split(result, size);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_chunk(void *data_start, chunk_t *result, int *category)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
void *chunk_pos;
|
||||||
|
|
||||||
|
for (i = TINY; i <= LARGE; i++)
|
||||||
|
{
|
||||||
|
chunk_pos = raw_get_chunk_by_root(allocs_tree[i], data_start);
|
||||||
|
if (chunk_pos == NULL)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (chunk_pos == NULL)
|
||||||
|
return 1;
|
||||||
|
chunk_read(chunk_pos, result);
|
||||||
|
if (category)
|
||||||
|
*category = i;
|
||||||
|
return 0;
|
||||||
}
|
}
|
@ -5,4 +5,5 @@
|
|||||||
void chunk_iter(chunk_t *root, void (*f)(chunk_t*));
|
void chunk_iter(chunk_t *root, void (*f)(chunk_t*));
|
||||||
void chunk_merge(chunk_t *first, chunk_t *second);
|
void chunk_merge(chunk_t *first, chunk_t *second);
|
||||||
int get_append_unused_chunk(void *root, size_t size, chunk_t *result, size_t new_block_size);
|
int get_append_unused_chunk(void *root, size_t size, chunk_t *result, size_t new_block_size);
|
||||||
int chunk_split(chunk_t *chunk, size_t new_size);
|
int chunk_split(chunk_t *chunk, size_t new_size);
|
||||||
|
int get_chunk(void *data_start, chunk_t *result, int *category);
|
70
src/free.c
Normal file
70
src/free.c
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include "chunk.h"
|
||||||
|
#include "malloc.h"
|
||||||
|
#include "chunk_manager.h"
|
||||||
|
#include "block.h"
|
||||||
|
#include "raw_chunk_manager.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
void free_tiny(chunk_t *chunk)
|
||||||
|
{
|
||||||
|
chunk_t chunk_prev, chunk_next, *first_chunk = chunk, *last_chunk = chunk;
|
||||||
|
|
||||||
|
if (chunk->prev)
|
||||||
|
{
|
||||||
|
chunk_read(chunk->prev, &chunk_prev);
|
||||||
|
if (chunk_prev.is_used == false && chunk_prev.block_id == chunk->block_id)
|
||||||
|
first_chunk = &chunk_prev;
|
||||||
|
}
|
||||||
|
if (chunk->next)
|
||||||
|
{
|
||||||
|
chunk_read(chunk->next, &chunk_next);
|
||||||
|
if (chunk_next.is_used == false && chunk_next.block_id == chunk->block_id)
|
||||||
|
last_chunk = &chunk_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
first_chunk->is_used = false;
|
||||||
|
chunk_merge(first_chunk, last_chunk);
|
||||||
|
|
||||||
|
if (is_alone_on_block(first_chunk))
|
||||||
|
{
|
||||||
|
if (first_chunk->current == allocs_tree[TINY])
|
||||||
|
allocs_tree[TINY] = last_chunk->next;
|
||||||
|
destroy_block(first_chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_small(chunk_t *chunk)
|
||||||
|
{
|
||||||
|
(void) chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_large(chunk_t *chunk)
|
||||||
|
{
|
||||||
|
if (chunk->current == allocs_tree[LARGE])
|
||||||
|
allocs_tree[LARGE] = chunk->next;
|
||||||
|
destroy_block(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void (*free_funcs[3])(chunk_t*) = {free_tiny, free_small, free_large};
|
||||||
|
|
||||||
|
void ft_free(void *ptr)
|
||||||
|
{
|
||||||
|
chunk_t chunk;
|
||||||
|
int category;
|
||||||
|
|
||||||
|
if (get_chunk(ptr, &chunk, &category))
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
write(2, "chunk not found\n", 16);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (chunk.is_used == false)
|
||||||
|
write(2, "double free\n", 12);
|
||||||
|
#endif
|
||||||
|
// CALL THE RIGHT FREE FUNCTION DEPEND ON SIZE
|
||||||
|
free_funcs[category](&chunk);
|
||||||
|
}
|
78
src/malloc.c
78
src/malloc.c
@ -66,82 +66,4 @@ void *ft_malloc(size_t size)
|
|||||||
if (size < m)
|
if (size < m)
|
||||||
return alloc_small(size);
|
return alloc_small(size);
|
||||||
return alloc_large(size);
|
return alloc_large(size);
|
||||||
}
|
|
||||||
|
|
||||||
void free_tiny(chunk_t *chunk)
|
|
||||||
{
|
|
||||||
chunk_t chunk_prev, chunk_next, *first_chunk = chunk, *last_chunk = chunk;
|
|
||||||
|
|
||||||
if (chunk->prev)
|
|
||||||
{
|
|
||||||
chunk_read(chunk->prev, &chunk_prev);
|
|
||||||
if (chunk_prev.is_used == false && chunk_prev.block_id == chunk->block_id)
|
|
||||||
first_chunk = &chunk_prev;
|
|
||||||
}
|
|
||||||
if (chunk->next)
|
|
||||||
{
|
|
||||||
chunk_read(chunk->next, &chunk_next);
|
|
||||||
if (chunk_next.is_used == false && chunk_next.block_id == chunk->block_id)
|
|
||||||
last_chunk = &chunk_next;
|
|
||||||
}
|
|
||||||
|
|
||||||
first_chunk->is_used = false;
|
|
||||||
chunk_merge(first_chunk, last_chunk);
|
|
||||||
|
|
||||||
if (is_alone_on_block(first_chunk))
|
|
||||||
{
|
|
||||||
if (first_chunk->current == allocs_tree[TINY])
|
|
||||||
allocs_tree[TINY] = last_chunk->next;
|
|
||||||
destroy_block(first_chunk);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_small(chunk_t *chunk)
|
|
||||||
{
|
|
||||||
(void) chunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_large(chunk_t *chunk)
|
|
||||||
{
|
|
||||||
if (chunk->current == allocs_tree[LARGE])
|
|
||||||
allocs_tree[LARGE] = chunk->next;
|
|
||||||
destroy_block(chunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void (*free_funcs[3])(chunk_t*) = {free_tiny, free_small, free_large};
|
|
||||||
|
|
||||||
void ft_free(void *ptr)
|
|
||||||
{
|
|
||||||
void **root;
|
|
||||||
void *raw_chunk;
|
|
||||||
chunk_t chunk;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
for (i = TINY; i <= LARGE + 1; i++)
|
|
||||||
{
|
|
||||||
if (i > LARGE)
|
|
||||||
{
|
|
||||||
// THROW ERROR
|
|
||||||
write(2, "chunk not found\n", 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
root = allocs_tree[i];
|
|
||||||
|
|
||||||
raw_chunk = raw_get_chunk(root, ptr);
|
|
||||||
if (raw_chunk == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
chunk_read(raw_chunk, &chunk);
|
|
||||||
|
|
||||||
if (chunk.is_used == false)
|
|
||||||
{
|
|
||||||
write(2, "double free\n", 12);
|
|
||||||
// THROW ERROR
|
|
||||||
}
|
|
||||||
|
|
||||||
// CALL THE RIGHT FREE FUNCTION DEPEND ON SIZE
|
|
||||||
free_funcs[i](&chunk);
|
|
||||||
}
|
}
|
@ -1,3 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#define DEBUG
|
||||||
|
|
||||||
extern void* allocs_tree[3];
|
extern void* allocs_tree[3];
|
@ -15,7 +15,7 @@ void *raw_get_last_chunk(void **root)
|
|||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *raw_get_chunk(void **root, void *data_start)
|
void *raw_get_chunk_by_root(void **root, void *data_start)
|
||||||
{
|
{
|
||||||
void**current = root;
|
void**current = root;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void *raw_get_last_chunk(void **root);
|
void *raw_get_last_chunk(void **root);
|
||||||
void *raw_get_chunk(void **root, void *data_start);
|
void *raw_get_chunk_by_root(void **root, void *data_start);
|
||||||
int get_unused_chunk_raw(void *root, size_t size, chunk_t *result);
|
int get_unused_chunk_raw(void *root, size_t size, chunk_t *result);
|
||||||
int is_alone_on_block(const chunk_t *chunk);
|
int is_alone_on_block(const chunk_t *chunk);
|
0
src/realloc.c
Normal file
0
src/realloc.c
Normal file
24
test/main.c
24
test/main.c
@ -37,13 +37,13 @@ int main(int ac, char **av)
|
|||||||
ptr1 = ft_malloc(10000000);
|
ptr1 = ft_malloc(10000000);
|
||||||
ptr2 = ft_malloc(10000000);
|
ptr2 = ft_malloc(10000000);
|
||||||
ptr3 = ft_malloc(10000000);
|
ptr3 = ft_malloc(10000000);
|
||||||
test(0, (const void*) (uintptr_t) (raw_get_chunk(allocs_tree[LARGE], ptr1) == NULL), "alloc first", "");
|
test(0, (const void*) (uintptr_t) (raw_get_chunk_by_root(allocs_tree[LARGE], ptr1) == NULL), "alloc first", "");
|
||||||
test(0, (const void*) (uintptr_t) (raw_get_chunk(allocs_tree[LARGE], ptr2) == NULL), "alloc second", "");
|
test(0, (const void*) (uintptr_t) (raw_get_chunk_by_root(allocs_tree[LARGE], ptr2) == NULL), "alloc second", "");
|
||||||
test(0, (const void*) (uintptr_t) (raw_get_chunk(allocs_tree[LARGE], ptr3) == NULL), "alloc third", "");
|
test(0, (const void*) (uintptr_t) (raw_get_chunk_by_root(allocs_tree[LARGE], ptr3) == NULL), "alloc third", "");
|
||||||
ft_free(ptr1);
|
ft_free(ptr1);
|
||||||
test(0, (const void*) (uintptr_t) (raw_get_chunk(allocs_tree[LARGE], ptr2) == NULL), "free disorder1", "");
|
test(0, (const void*) (uintptr_t) (raw_get_chunk_by_root(allocs_tree[LARGE], ptr2) == NULL), "free disorder1", "");
|
||||||
ft_free(ptr3);
|
ft_free(ptr3);
|
||||||
test(0, (const void*) (uintptr_t) (raw_get_chunk(allocs_tree[LARGE], ptr2) == NULL), "free disorder2", "");
|
test(0, (const void*) (uintptr_t) (raw_get_chunk_by_root(allocs_tree[LARGE], ptr2) == NULL), "free disorder2", "");
|
||||||
ft_free(ptr2);
|
ft_free(ptr2);
|
||||||
test(NULL, allocs_tree[LARGE], "free disorder3", "");
|
test(NULL, allocs_tree[LARGE], "free disorder3", "");
|
||||||
|
|
||||||
@ -57,18 +57,16 @@ int main(int ac, char **av)
|
|||||||
ptr1 = ft_malloc(4);
|
ptr1 = ft_malloc(4);
|
||||||
ptr2 = ft_malloc(4);
|
ptr2 = ft_malloc(4);
|
||||||
ptr3 = ft_malloc(4);
|
ptr3 = ft_malloc(4);
|
||||||
test(0, (const void*) (uintptr_t) (raw_get_chunk(allocs_tree[TINY], ptr1) == NULL), "alloc first", "");
|
test(0, (const void*) (uintptr_t) (raw_get_chunk_by_root(allocs_tree[TINY], ptr1) == NULL), "alloc first", "");
|
||||||
test(0, (const void*) (uintptr_t) (raw_get_chunk(allocs_tree[TINY], ptr2) == NULL), "alloc second", "");
|
test(0, (const void*) (uintptr_t) (raw_get_chunk_by_root(allocs_tree[TINY], ptr2) == NULL), "alloc second", "");
|
||||||
test(0, (const void*) (uintptr_t) (raw_get_chunk(allocs_tree[TINY], ptr3) == NULL), "alloc third", "");
|
test(0, (const void*) (uintptr_t) (raw_get_chunk_by_root(allocs_tree[TINY], ptr3) == NULL), "alloc third", "");
|
||||||
show_alloc_mem();
|
|
||||||
ft_free(ptr1);
|
ft_free(ptr1);
|
||||||
test(0, (const void*) (uintptr_t) (raw_get_chunk(allocs_tree[TINY], ptr2) == NULL), "free disorder1", "");
|
test(0, (const void*) (uintptr_t) (raw_get_chunk_by_root(allocs_tree[TINY], ptr2) == NULL), "free disorder1", "");
|
||||||
ft_free(ptr3);
|
ft_free(ptr3);
|
||||||
test(0, (const void*) (uintptr_t) (raw_get_chunk(allocs_tree[TINY], ptr2) == NULL), "free disorder2", "");
|
test(0, (const void*) (uintptr_t) (raw_get_chunk_by_root(allocs_tree[TINY], ptr2) == NULL), "free disorder2", "");
|
||||||
show_alloc_mem();
|
|
||||||
ft_free(ptr2);
|
ft_free(ptr2);
|
||||||
show_alloc_mem();
|
|
||||||
test(NULL, allocs_tree[TINY], "free disorder3", "");
|
test(NULL, allocs_tree[TINY], "free disorder3", "");
|
||||||
|
show_alloc_mem();
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user