copy on git
This commit is contained in:
commit
42653de246
205 changed files with 7459 additions and 0 deletions
85
srcs/bonus_utils.c
Normal file
85
srcs/bonus_utils.c
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* bonus_utils.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/11/28 16:42:13 by thrieg #+# #+# */
|
||||
/* Updated: 2025/11/28 18:25:49 by thrieg ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../includes/ft_malloc.h"
|
||||
#include "../libft/ft_printf/ft_printf.h"
|
||||
|
||||
// bytes_per_line has to be a power of 2
|
||||
static void hexdump_block(void *addr, size_t size, size_t bytes_per_Line)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)addr;
|
||||
uintptr_t start = (uintptr_t)p;
|
||||
uintptr_t end = start + size;
|
||||
|
||||
// align down to bytes_per_Line bytes
|
||||
uintptr_t line_start = start & ~(uintptr_t)(bytes_per_Line - 1);
|
||||
|
||||
while (line_start < end)
|
||||
{
|
||||
ft_printf("%p: ", (void *)line_start);
|
||||
|
||||
for (size_t i = 0; i < bytes_per_Line; ++i)
|
||||
{
|
||||
uintptr_t pos = line_start + (uintptr_t)i;
|
||||
|
||||
if (pos < start || pos >= end)
|
||||
{
|
||||
// outside the block; print spaces to keep alignment
|
||||
ft_printf(" ");
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char byte = *(unsigned char *)pos;
|
||||
ft_printf("%02x ", (unsigned int)byte);
|
||||
}
|
||||
}
|
||||
ft_printf("\n");
|
||||
line_start += bytes_per_Line;
|
||||
}
|
||||
}
|
||||
|
||||
void print_zone(t_zone *zone, bool hexdump_free_zones)
|
||||
{
|
||||
ft_printf("--------------------------------\n");
|
||||
ft_printf("new %s zone:\n", zone->type == E_TINY ? "tiny" : (zone->type == E_SMALL ? "small" : "large"));
|
||||
ft_printf("size: %u\n", (unsigned int)zone->size);
|
||||
ft_printf("--------------------------------\n");
|
||||
|
||||
char *zone_end = (char *)zone + zone->size;
|
||||
t_header *header = (t_header *)(zone + 1);
|
||||
while ((char *)header + sizeof(t_header) <= zone_end)
|
||||
{
|
||||
ft_printf("--------------------------------\n");
|
||||
ft_printf("new %s header:\n", header->occupied ? "allocated" : "free");
|
||||
ft_printf("size: %u\n", (unsigned int)header->size);
|
||||
ft_printf("--------------------------------\n");
|
||||
if (header->occupied || hexdump_free_zones)
|
||||
hexdump_block(header + 1, header->size, 16);
|
||||
header = (t_header *)((char *)(header + 1) + header->size);
|
||||
}
|
||||
}
|
||||
|
||||
void print_all_zones(t_zone *first_zone, bool hexdump_free_zones)
|
||||
{
|
||||
while (first_zone)
|
||||
{
|
||||
print_zone(first_zone, hexdump_free_zones);
|
||||
first_zone = first_zone->next;
|
||||
}
|
||||
}
|
||||
|
||||
void show_alloc_mem_ex(bool hexdump_free_zones)
|
||||
{
|
||||
print_all_zones(g_state.tiny_zone, hexdump_free_zones);
|
||||
print_all_zones(g_state.small_zone, hexdump_free_zones);
|
||||
print_all_zones(g_state.large_zone, hexdump_free_zones);
|
||||
}
|
||||
BIN
srcs/bonus_utils.o
Normal file
BIN
srcs/bonus_utils.o
Normal file
Binary file not shown.
29
srcs/ft_calloc.c
Normal file
29
srcs/ft_calloc.c
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* ft_calloc.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/11/25 11:47:16 by thrieg #+# #+# */
|
||||
/* Updated: 2025/11/28 16:41:16 by thrieg ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../includes/ft_malloc.h"
|
||||
|
||||
void *calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
size_t real_size = nmemb * size;
|
||||
void *malloc_ret;
|
||||
|
||||
if (real_size % ALLIGN_BYTES)
|
||||
real_size = ((real_size / ALLIGN_BYTES) + 1) * ALLIGN_BYTES;
|
||||
malloc_ret = malloc(real_size);
|
||||
if (!malloc_ret)
|
||||
return (NULL);
|
||||
// pthread_mutex_lock(&g_mut);
|
||||
ft_memset(malloc_ret, 0, real_size); // no need to lock because pointer is internal until we return it, user can't call any of our function on it
|
||||
// pthread_mutex_unlock(&g_mut);
|
||||
return (malloc_ret);
|
||||
}
|
||||
BIN
srcs/ft_calloc.o
Normal file
BIN
srcs/ft_calloc.o
Normal file
Binary file not shown.
99
srcs/ft_free.c
Normal file
99
srcs/ft_free.c
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* ft_free.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/11/19 15:44:05 by thrieg #+# #+# */
|
||||
/* Updated: 2025/11/25 16:21:10 by thrieg ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../includes/ft_malloc.h"
|
||||
|
||||
// returns non-0 (1) when the function munmap the zone
|
||||
int defrag_zone(t_zone *zone)
|
||||
{
|
||||
t_header *header = (t_header *)(zone + 1);
|
||||
char *last_adr = ((char *)zone) + zone->size - sizeof(t_header);
|
||||
while ((((char *)header) + header->size) < last_adr)
|
||||
{
|
||||
t_header *next_header = (t_header *)(((char *)header) + sizeof(t_header) + header->size);
|
||||
if (!header->occupied && !next_header->occupied)
|
||||
{
|
||||
header->size = header->size + sizeof(t_header) + next_header->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
header = next_header;
|
||||
}
|
||||
}
|
||||
// if only 1 free header left, mmunmap the zone
|
||||
if (header == (t_header *)(zone + 1) && !header->occupied)
|
||||
{
|
||||
if (zone->type == E_SMALL)
|
||||
{
|
||||
if (g_state.small_zone == zone)
|
||||
{
|
||||
if (zone->next)
|
||||
g_state.small_zone = zone->next;
|
||||
else
|
||||
return (0); // last small zone, don't deallocate to avoid mmap stress
|
||||
}
|
||||
}
|
||||
else if (zone->type == E_TINY)
|
||||
{
|
||||
if (g_state.tiny_zone == zone)
|
||||
{
|
||||
if (zone->next)
|
||||
g_state.tiny_zone = zone->next;
|
||||
else
|
||||
return (0); // last tiny zone, don't deallocate to avoid mmap stress
|
||||
}
|
||||
}
|
||||
if (zone->prev)
|
||||
zone->prev->next = zone->next;
|
||||
if (zone->next)
|
||||
zone->next->prev = zone->prev;
|
||||
munmap(zone, zone->size);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void free(void *ptr)
|
||||
{
|
||||
pthread_mutex_lock(&g_mut);
|
||||
if (!ptr)
|
||||
return ((void)pthread_mutex_unlock(&g_mut));
|
||||
t_header *header = ((t_header *)ptr) - 1;
|
||||
if (header->zone->type == E_LARGE)
|
||||
{
|
||||
if (header->zone->prev)
|
||||
header->zone->prev->next = header->zone->next;
|
||||
if (header->zone->next)
|
||||
header->zone->next->prev = header->zone->prev;
|
||||
if (header->zone == g_state.large_zone)
|
||||
{
|
||||
if (g_state.large_zone->next)
|
||||
g_state.large_zone = g_state.large_zone->next;
|
||||
else
|
||||
g_state.large_zone = NULL;
|
||||
}
|
||||
void *ptr = header->zone;
|
||||
size_t len = header->zone->size;
|
||||
munmap(ptr, len);
|
||||
}
|
||||
else if (header->zone->type == E_SMALL)
|
||||
{
|
||||
header->occupied = false;
|
||||
defrag_zone(header->zone);
|
||||
}
|
||||
else if (header->zone->type == E_TINY)
|
||||
{
|
||||
header->occupied = false;
|
||||
defrag_zone(header->zone);
|
||||
}
|
||||
pthread_mutex_unlock(&g_mut);
|
||||
}
|
||||
BIN
srcs/ft_free.o
Normal file
BIN
srcs/ft_free.o
Normal file
Binary file not shown.
35
srcs/ft_malloc.c
Normal file
35
srcs/ft_malloc.c
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* ft_malloc.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/11/17 15:02:55 by thrieg #+# #+# */
|
||||
/* Updated: 2025/11/25 14:30:44 by thrieg ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../includes/ft_malloc.h"
|
||||
|
||||
void *malloc(size_t size)
|
||||
{
|
||||
pthread_mutex_lock(&g_mut);
|
||||
if (!size || size % ALLIGN_BYTES)
|
||||
size = ((size / ALLIGN_BYTES) + 1) * ALLIGN_BYTES;
|
||||
void *ret = NULL;
|
||||
if (size > SMALL_SIZE_MAX)
|
||||
{
|
||||
ret = add_large(size);
|
||||
}
|
||||
else if (size > TINY_SIZE_MAX)
|
||||
{
|
||||
ret = add_small(size);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = add_tiny(size);
|
||||
}
|
||||
pthread_mutex_unlock(&g_mut);
|
||||
return (ret);
|
||||
}
|
||||
BIN
srcs/ft_malloc.o
Normal file
BIN
srcs/ft_malloc.o
Normal file
Binary file not shown.
146
srcs/ft_realloc.c
Normal file
146
srcs/ft_realloc.c
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* ft_realloc.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/11/25 11:47:23 by thrieg #+# #+# */
|
||||
/* Updated: 2025/11/28 16:37:22 by thrieg ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../includes/ft_malloc.h"
|
||||
|
||||
// returns non-0 (1) is the zone changes type to a higher type (tiny to small or small to large)
|
||||
static bool is_upgraded(size_t size, t_type current_type)
|
||||
{
|
||||
if (size > SMALL_SIZE_MAX && current_type != E_LARGE)
|
||||
return (1);
|
||||
else if (size > TINY_SIZE_MAX && current_type != E_SMALL)
|
||||
return (1);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
void *realloc(void *ptr, size_t size)
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
free(ptr);
|
||||
return (NULL);
|
||||
}
|
||||
else if (!ptr)
|
||||
{
|
||||
return (malloc(size));
|
||||
}
|
||||
size_t original_size = size;
|
||||
if (size % ALLIGN_BYTES)
|
||||
size = ((size / ALLIGN_BYTES) + 1) * ALLIGN_BYTES;
|
||||
void *ret = NULL;
|
||||
pthread_mutex_lock(&g_mut);
|
||||
t_header *header = ((t_header *)ptr) - 1;
|
||||
if (header->zone->type == E_LARGE)
|
||||
{
|
||||
pthread_mutex_unlock(&g_mut);
|
||||
ret = malloc(size);
|
||||
if (!ret)
|
||||
return (NULL);
|
||||
pthread_mutex_lock(&g_mut);
|
||||
if (original_size > header->size)
|
||||
ft_memcpy(ret, ptr, header->size); // if grow, copy the entire last buffer
|
||||
else
|
||||
ft_memcpy(ret, ptr, original_size); // if shrink, copy the new amount of bytes from older buffer
|
||||
pthread_mutex_unlock(&g_mut);
|
||||
free(ptr);
|
||||
pthread_mutex_lock(&g_mut);
|
||||
}
|
||||
else if (is_upgraded(size, header->zone->type))
|
||||
{
|
||||
pthread_mutex_unlock(&g_mut);
|
||||
ret = malloc(size);
|
||||
if (!ret)
|
||||
return (NULL);
|
||||
pthread_mutex_lock(&g_mut);
|
||||
if (original_size > header->size)
|
||||
ft_memcpy(ret, ptr, header->size); // if grow, copy the entire last buffer
|
||||
else
|
||||
ft_memcpy(ret, ptr, original_size); // if shrink, copy the new amount of bytes from older buffer
|
||||
pthread_mutex_unlock(&g_mut);
|
||||
free(ptr);
|
||||
pthread_mutex_lock(&g_mut);
|
||||
}
|
||||
else if (header->zone->type == E_SMALL || header->zone->type == E_TINY)
|
||||
{
|
||||
t_header *next_header = (t_header *)(((char *)header) + sizeof(t_header) + header->size);
|
||||
if ((char *)next_header > (((char *)header->zone) + header->zone->size - sizeof(t_header)))
|
||||
next_header = NULL; // next header out of the zone
|
||||
if (size > header->size)
|
||||
{
|
||||
if (next_header && !next_header->occupied && (header->size + next_header->size + sizeof(t_header)) >= size)
|
||||
{
|
||||
const size_t available_space = (header->size + next_header->size + sizeof(t_header));
|
||||
if (available_space - size > sizeof(t_header))
|
||||
{
|
||||
// Split the block: create a new header in the remaining space
|
||||
char *new_addr = (char *)(header + 1) + size;
|
||||
t_header *newhdr = (t_header *)new_addr;
|
||||
|
||||
newhdr->size = available_space - size - sizeof(t_header);
|
||||
newhdr->occupied = false;
|
||||
newhdr->zone = header->zone;
|
||||
|
||||
header->size = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
header->size = available_space;
|
||||
}
|
||||
ret = ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
pthread_mutex_unlock(&g_mut);
|
||||
ret = malloc(size);
|
||||
if (!ret)
|
||||
return (NULL);
|
||||
pthread_mutex_lock(&g_mut);
|
||||
if (original_size > header->size)
|
||||
ft_memcpy(ret, ptr, header->size); // if grow, copy the entire last buffer
|
||||
else
|
||||
ft_memcpy(ret, ptr, original_size); // if shrink, copy the new amount of bytes from older buffer
|
||||
pthread_mutex_unlock(&g_mut);
|
||||
free(ptr);
|
||||
pthread_mutex_lock(&g_mut);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = ptr; // in all case we just return the original ptr, rest is just internal logic
|
||||
size_t available_space = header->size - size; // zones are defragmented so all available contiguous space must be in a single header
|
||||
if (next_header && !next_header->occupied)
|
||||
available_space += next_header->size + sizeof(t_header);
|
||||
if (available_space > sizeof(t_header))
|
||||
{
|
||||
if (available_space > sizeof(t_header))
|
||||
{
|
||||
// Split the block: create a new header in the remaining space
|
||||
char *new_addr = (char *)(header + 1) + size;
|
||||
t_header *newhdr = (t_header *)new_addr;
|
||||
|
||||
newhdr->size = available_space - sizeof(t_header);
|
||||
newhdr->occupied = false;
|
||||
newhdr->zone = header->zone;
|
||||
|
||||
header->size = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
header->size = available_space;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&g_mut);
|
||||
return (ret);
|
||||
}
|
||||
BIN
srcs/ft_realloc.o
Normal file
BIN
srcs/ft_realloc.o
Normal file
Binary file not shown.
267
srcs/init_state.c
Normal file
267
srcs/init_state.c
Normal file
|
|
@ -0,0 +1,267 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* init_state.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: thrieg < thrieg@student.42mulhouse.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2025/11/18 16:44:13 by thrieg #+# #+# */
|
||||
/* Updated: 2025/11/28 16:41:55 by thrieg ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../includes/ft_malloc.h"
|
||||
|
||||
pthread_mutex_t g_mut = PTHREAD_MUTEX_INITIALIZER;
|
||||
t_state g_state = {.tiny_zone = NULL, .small_zone = NULL, .large_zone = NULL};
|
||||
|
||||
// only call this for TINY or SMALL
|
||||
void *add_page(t_type type)
|
||||
{
|
||||
size_t size;
|
||||
if (type == E_TINY)
|
||||
size = ((((((TINY_SIZE_MAX + sizeof(t_header)) * 100) + sizeof(t_zone))) / getpagesize()) + 1) * getpagesize();
|
||||
else if (type == E_SMALL)
|
||||
size = ((((((SMALL_SIZE_MAX + sizeof(t_header)) * 100) + sizeof(t_zone))) / getpagesize()) + 1) * getpagesize();
|
||||
else
|
||||
return (NULL); // TODO handle error somehow
|
||||
t_zone *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
if (ptr == MAP_FAILED)
|
||||
return (NULL);
|
||||
ptr->size = size;
|
||||
if (type == E_TINY)
|
||||
{
|
||||
ptr->type = E_TINY;
|
||||
ptr->prev = NULL;
|
||||
t_header *header = (t_header *)(ptr + 1);
|
||||
header->occupied = false;
|
||||
header->size = size - sizeof(t_zone) - sizeof(t_header);
|
||||
header->zone = ptr;
|
||||
ptr->next = g_state.tiny_zone; // tiny_zone can be NULL but that's fine
|
||||
if (g_state.tiny_zone)
|
||||
g_state.tiny_zone->prev = ptr;
|
||||
g_state.tiny_zone = ptr;
|
||||
}
|
||||
else if (type == E_SMALL)
|
||||
{
|
||||
ptr->type = E_SMALL;
|
||||
ptr->prev = NULL;
|
||||
t_header *header = (t_header *)(ptr + 1);
|
||||
header->occupied = false;
|
||||
header->size = size - sizeof(t_zone) - sizeof(t_header);
|
||||
header->zone = ptr;
|
||||
ptr->next = g_state.small_zone; // small_zone can be NULL but that's fine
|
||||
if (g_state.small_zone)
|
||||
g_state.small_zone->prev = ptr;
|
||||
g_state.small_zone = ptr;
|
||||
}
|
||||
return (ptr);
|
||||
}
|
||||
|
||||
// returns the start of the buffer (returned by malloc)
|
||||
void *add_large(size_t size)
|
||||
{
|
||||
size = (((size + sizeof(t_header) + sizeof(t_zone)) / getpagesize()) + 1) * getpagesize();
|
||||
t_zone *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
if (ptr == MAP_FAILED)
|
||||
return (NULL);
|
||||
ptr->size = size;
|
||||
ptr->type = E_LARGE;
|
||||
ptr->prev = NULL;
|
||||
ptr->next = g_state.large_zone; // large_zone can be NULL but that's fine
|
||||
if (g_state.large_zone)
|
||||
g_state.large_zone->prev = ptr;
|
||||
g_state.large_zone = ptr;
|
||||
t_header *header = (t_header *)(ptr + 1);
|
||||
header->occupied = true;
|
||||
header->size = size - sizeof(t_zone) - sizeof(t_header);
|
||||
header->zone = ptr;
|
||||
return ((void *)(header + 1));
|
||||
}
|
||||
|
||||
// returns the start of the buffer (returned by malloc)
|
||||
// size has to be alligned
|
||||
void *add_small(size_t size)
|
||||
{
|
||||
t_zone *zone;
|
||||
t_header *hdr;
|
||||
void *result = NULL;
|
||||
|
||||
zone = g_state.small_zone;
|
||||
while (zone && !result)
|
||||
{
|
||||
char *zone_start = (char *)zone;
|
||||
char *zone_end = zone_start + zone->size;
|
||||
|
||||
// First header is right after the zone struct
|
||||
hdr = (t_header *)(zone + 1);
|
||||
|
||||
while ((char *)hdr + sizeof(t_header) <= zone_end)
|
||||
{
|
||||
if (!hdr->occupied && hdr->size >= size)
|
||||
{
|
||||
// Found a free block big enough
|
||||
size_t remaining = hdr->size - size;
|
||||
|
||||
if (remaining > sizeof(t_header))
|
||||
{
|
||||
// Split the block: create a new header in the remaining space
|
||||
char *new_addr = (char *)(hdr + 1) + size;
|
||||
t_header *newhdr = (t_header *)new_addr;
|
||||
|
||||
newhdr->size = remaining - sizeof(t_header);
|
||||
newhdr->occupied = false;
|
||||
newhdr->zone = zone;
|
||||
|
||||
hdr->size = size;
|
||||
}
|
||||
// else: not enough room for another header, we just don't touch the size
|
||||
|
||||
hdr->occupied = true;
|
||||
result = (void *)(hdr + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
char *next_addr = (char *)(hdr + 1) + hdr->size;
|
||||
|
||||
// If there's no room for another valid header, stop.
|
||||
if (next_addr + sizeof(t_header) > zone_end)
|
||||
break;
|
||||
|
||||
hdr = (t_header *)next_addr;
|
||||
}
|
||||
|
||||
zone = zone->next;
|
||||
}
|
||||
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
// not enough room, create a new page
|
||||
zone = (t_zone *)add_page(E_SMALL);
|
||||
if (!zone)
|
||||
return (NULL);
|
||||
|
||||
hdr = (t_header *)(zone + 1);
|
||||
|
||||
if (hdr->size >= size)
|
||||
{
|
||||
size_t remaining = hdr->size - size;
|
||||
|
||||
if (remaining > sizeof(t_header)) // should always be true (enough room for 100 allocs in a page)
|
||||
{
|
||||
char *new_addr = (char *)(hdr + 1) + size;
|
||||
t_header *newhdr = (t_header *)new_addr;
|
||||
|
||||
newhdr->size = remaining - sizeof(t_header);
|
||||
newhdr->occupied = false;
|
||||
newhdr->zone = zone;
|
||||
|
||||
hdr->size = size;
|
||||
}
|
||||
hdr->occupied = true;
|
||||
result = (void *)(hdr + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// wtf, not possible, but nice to handle I guess
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
// returns the start of the buffer (returned by malloc)
|
||||
// size has to be alligned
|
||||
void *add_tiny(size_t size)
|
||||
{
|
||||
t_zone *zone;
|
||||
t_header *hdr;
|
||||
void *result = NULL;
|
||||
|
||||
zone = g_state.tiny_zone;
|
||||
while (zone && !result)
|
||||
{
|
||||
char *zone_start = (char *)zone;
|
||||
char *zone_end = zone_start + zone->size;
|
||||
|
||||
// First header is right after the zone struct
|
||||
hdr = (t_header *)(zone + 1);
|
||||
|
||||
while ((char *)hdr + sizeof(t_header) <= zone_end)
|
||||
{
|
||||
if (!hdr->occupied && hdr->size >= size)
|
||||
{
|
||||
// Found a free block big enough
|
||||
size_t remaining = hdr->size - size;
|
||||
|
||||
if (remaining > sizeof(t_header))
|
||||
{
|
||||
// Split the block: create a new header in the remaining space
|
||||
char *new_addr = (char *)(hdr + 1) + size;
|
||||
t_header *newhdr = (t_header *)new_addr;
|
||||
|
||||
newhdr->size = remaining - sizeof(t_header);
|
||||
newhdr->occupied = false;
|
||||
newhdr->zone = zone;
|
||||
|
||||
hdr->size = size;
|
||||
}
|
||||
// else: not enough room for another header, we just
|
||||
|
||||
hdr->occupied = true;
|
||||
result = (void *)(hdr + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
char *next_addr = (char *)(hdr + 1) + hdr->size;
|
||||
|
||||
// If there's no room for another valid header, stop.
|
||||
if (next_addr + sizeof(t_header) > zone_end)
|
||||
break;
|
||||
|
||||
hdr = (t_header *)next_addr;
|
||||
}
|
||||
|
||||
zone = zone->next;
|
||||
}
|
||||
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
// not enough room, create a new page
|
||||
zone = (t_zone *)add_page(E_TINY);
|
||||
if (!zone)
|
||||
return (NULL);
|
||||
|
||||
hdr = (t_header *)(zone + 1);
|
||||
|
||||
// hdr->size should always be >= size here
|
||||
if (hdr->size >= size)
|
||||
{
|
||||
size_t remaining = hdr->size - size;
|
||||
|
||||
if (remaining > sizeof(t_header)) // should always be true (enough room for 100 allocs in a page)
|
||||
{
|
||||
char *new_addr = (char *)(hdr + 1) + size;
|
||||
t_header *newhdr = (t_header *)new_addr;
|
||||
|
||||
newhdr->size = remaining - sizeof(t_header);
|
||||
newhdr->occupied = false;
|
||||
newhdr->zone = zone;
|
||||
|
||||
hdr->size = size;
|
||||
}
|
||||
hdr->occupied = true;
|
||||
result = (void *)(hdr + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// wtf, not possible, but nice to handle I guess
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
BIN
srcs/init_state.o
Normal file
BIN
srcs/init_state.o
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue