#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; }