ft_malloc/src/malloc.c

169 lines
4.7 KiB
C

#include "malloc.h"
t_zone *create_new_tiny_zone(void) {
t_zone *zone;
// TODO protect mmap
zone = (t_zone *)mmap(NULL, g_zones.tiny_zone_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
zone->head = NULL;
zone->next = NULL;
return zone;
}
void *malloc_tiny(size_t size) {
t_zone *zone = g_zones.tiny_zones;
while (1) {
t_block *curr = zone->head;
if (curr == NULL) {
// TODO size_t should be replaced by char * for pointer arithmetic
size_t addr = ((size_t)zone + sizeof(t_zone));
if ((addr + sizeof(t_block)) % 16 != 0) {
addr += 16 - ((addr + sizeof(t_block)) % 16);
}
zone->head = (t_block *)addr;
curr = zone->head;
printf("addr of g_zones.tiny_zones : %p\n"
"addr of zone : %p\n"
"addr of *head %p\n"
"sizeof tzone : %zu\n"
"size of tblock %zu\n",
g_zones.tiny_zones,
zone,
curr,
sizeof(t_zone),
sizeof(t_block));
curr->size = size;
curr->free = 0;
curr->next = NULL;
return (void *)((char *)(curr) + sizeof(t_block));
}
else {
while (curr->next) {
// todo check if free and defrag
curr = curr->next;
}
// TODO size_t should be replaced by char * for pointer arithmetic
size_t addr = (size_t)curr + sizeof(t_block) + curr->size;
if ((addr + sizeof(t_block)) % 16 != 0) {
addr += 16 - ((addr + sizeof(t_block)) % 16);
}
if (((size_t)zone + g_zones.tiny_zone_size) - addr >= size + sizeof(t_block) + (16 - sizeof(t_block) % 16))
{
curr->next = (t_block *)addr;
curr = curr->next;
curr->size = size;
curr->free = 0;
curr->next = NULL;
return (void *)((char *)curr + sizeof(t_block));
}
if (zone->next == NULL) {
zone->next = create_new_tiny_zone();
}
zone = zone->next;
}
}
return NULL;
}
t_zone *create_new_small_zone(void) {
t_zone *zone;
// TODO protect mmap
zone = (t_zone *)mmap(NULL, g_zones.small_zone_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
zone->head = NULL;
zone->next = NULL;
return zone;
}
void *malloc_small(size_t size) {
t_zone *zone = g_zones.small_zones;
while (1) {
t_block *curr = zone->head;
if (curr == NULL) {
// TODO size_t should be replaced by char * for pointer arithmetic
size_t addr = ((size_t)zone + sizeof(t_zone));
if ((addr + sizeof(t_block)) % 16 != 0) {
addr += 16 - ((addr + sizeof(t_block)) % 16);
}
zone->head = (t_block *)addr;
curr = zone->head;
printf("addr of g_zones.small_zones : %p\n"
"addr of zone : %p\n"
"addr of *head %p\n"
"sizeof tzone : %zu\n"
"size of tblock %zu\n",
g_zones.small_zones,
zone,
curr,
sizeof(t_zone),
sizeof(t_block));
curr->size = size;
curr->free = 0;
curr->next = NULL;
return (void *)((char *)(curr) + sizeof(t_block));
}
else {
while (curr->next) {
// todo check if free and defrag
curr = curr->next;
}
// TODO size_t should be replaced by char * for pointer arithmetic
size_t addr = (size_t)curr + sizeof(t_block) + curr->size;
if ((addr + sizeof(t_block)) % 16 != 0) {
addr += 16 - ((addr + sizeof(t_block)) % 16);
}
if (((size_t)zone + g_zones.small_zone_size) - addr >= size + sizeof(t_block) + (16 - sizeof(t_block) % 16))
{
curr->next = (t_block *)addr;
curr = curr->next;
curr->size = size;
curr->free = 0;
curr->next = NULL;
return (void *)((char *)curr + sizeof(t_block));
}
if (zone->next == NULL) {
zone->next = create_new_small_zone();
}
zone = zone->next;
}
}
return NULL;
}
void *malloc_large(size_t size) {
t_block *curr = g_zones.large_blocks;
if (curr == NULL) {
// TODO protect mmap
curr = (t_block *)((char *)mmap(NULL, size + sizeof(t_block) + (16 - sizeof(t_block) % 16), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) + (16 - sizeof(t_block) % 16));
curr->size = size;
curr->free = 0;
curr->next = NULL;
return (void *)((char *)curr + sizeof(t_block));
}
while (curr->next) {
curr = curr->next;
}
// TODO protect mmap
curr->next = (t_block *)((char *)mmap(NULL, size + sizeof(t_block) + (16 - sizeof(t_block) % 16), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) + (16 - sizeof(t_block) % 16));
curr = curr->next;
curr->size = size;
curr->free = 0;
curr->next = NULL;
return (void *)((char *)curr + sizeof(t_block));
}
void *ft_malloc(size_t size) {
pthread_mutex_lock(&g_malloc_mutex);
void *ptr = NULL;
if (size < g_zones.tiny_block_max_size) {
ptr = malloc_tiny(size);
} else if (size < g_zones.small_block_max_size) {
ptr = malloc_small(size);
} else {
ptr = malloc_large(size);
}
pthread_mutex_unlock(&g_malloc_mutex);
return ptr;
}