feat: malloc multi zones and large blocks
This commit is contained in:
parent
8b7d7ca958
commit
912064ae31
|
@ -29,7 +29,9 @@ typedef struct s_zones {
|
||||||
size_t pagesize;
|
size_t pagesize;
|
||||||
size_t max_align;
|
size_t max_align;
|
||||||
size_t tiny_block_max_size;
|
size_t tiny_block_max_size;
|
||||||
|
size_t tiny_zone_size;
|
||||||
size_t small_block_max_size;
|
size_t small_block_max_size;
|
||||||
|
size_t small_zone_size;
|
||||||
t_zone *tiny_zones;
|
t_zone *tiny_zones;
|
||||||
t_zone *small_zones;
|
t_zone *small_zones;
|
||||||
t_block *large_blocks;
|
t_block *large_blocks;
|
||||||
|
|
19
main.c
19
main.c
|
@ -1,16 +1,15 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "inc/malloc.h"
|
#include "inc/malloc.h"
|
||||||
|
|
||||||
int main(void) {
|
int main(int argc, char **argv) {
|
||||||
int *arr = ft_malloc(42);
|
srand(argv[1][0]+argv[1][1]+argv[1][2]);
|
||||||
printf ("addr of arr is : %p\n", arr);
|
int *arr;
|
||||||
arr = realloc(arr, 42);
|
size_t size;
|
||||||
int *arr2 = ft_malloc(124);
|
for (int i = 0; i < atoi(argv[2]); i++) {
|
||||||
int *arr3 = ft_malloc(1540);
|
size = (rand() & 0x7ff) | 0xf00000;
|
||||||
printf ("addr of arr is : %p\n", arr);
|
arr = (int *)ft_malloc(size * sizeof(int));
|
||||||
printf ("addr of arr2 is : %p\n", arr2);
|
printf ("arr %d addr: %p arr size: %zu\n", i, arr, size);
|
||||||
printf ("addr of arr3 is : %p\n", arr3);
|
}
|
||||||
free(arr);
|
|
||||||
show_alloc_sizes();
|
show_alloc_sizes();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,16 +5,18 @@ t_zones g_zones;
|
||||||
|
|
||||||
void init_tiny_zones(void) {
|
void init_tiny_zones(void) {
|
||||||
g_zones.tiny_block_max_size = g_zones.pagesize / 2;
|
g_zones.tiny_block_max_size = g_zones.pagesize / 2;
|
||||||
|
g_zones.tiny_zone_size = g_zones.tiny_block_max_size * 128;
|
||||||
// TODO protect mmap
|
// TODO protect mmap
|
||||||
g_zones.tiny_zones = (t_zone *)mmap(NULL, g_zones.tiny_block_max_size * 128, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
g_zones.tiny_zones = (t_zone *)mmap(NULL, g_zones.tiny_zone_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
g_zones.tiny_zones->head = NULL;
|
g_zones.tiny_zones->head = NULL;
|
||||||
g_zones.tiny_zones->next = NULL;
|
g_zones.tiny_zones->next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_small_zones(void) {
|
void init_small_zones(void) {
|
||||||
g_zones.small_block_max_size = g_zones.tiny_block_max_size * 128;
|
g_zones.small_block_max_size = g_zones.tiny_block_max_size * 128;
|
||||||
|
g_zones.small_zone_size = g_zones.small_block_max_size * 128;
|
||||||
// TODO protect mmap
|
// TODO protect mmap
|
||||||
g_zones.small_zones = (t_zone *)mmap(NULL, g_zones.small_block_max_size * 128, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
g_zones.small_zones = (t_zone *)mmap(NULL, g_zones.small_zone_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
g_zones.small_zones->head = NULL;
|
g_zones.small_zones->head = NULL;
|
||||||
g_zones.small_zones->next = NULL;
|
g_zones.small_zones->next = NULL;
|
||||||
}
|
}
|
||||||
|
@ -25,5 +27,6 @@ static void init_malloc(void) {
|
||||||
g_zones.max_align = MAX_ALIGNMENT;
|
g_zones.max_align = MAX_ALIGNMENT;
|
||||||
init_tiny_zones();
|
init_tiny_zones();
|
||||||
init_small_zones();
|
init_small_zones();
|
||||||
|
g_zones.large_blocks = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
191
src/malloc.c
191
src/malloc.c
|
@ -1,78 +1,167 @@
|
||||||
#include "malloc.h"
|
#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) {
|
void *malloc_tiny(size_t size) {
|
||||||
// TODO check if zone still has size and expand zone if needed
|
t_zone *zone = g_zones.tiny_zones;
|
||||||
t_block **head = &(g_zones.tiny_zones->head);
|
|
||||||
if (*head == NULL) {
|
while (1) {
|
||||||
// TODO size_t should be replaced by char * for pointer arithmetic
|
t_block *curr = zone->head;
|
||||||
size_t addr = ((size_t)g_zones.tiny_zones + sizeof(t_zone));
|
if (curr == NULL) {
|
||||||
printf("addr %zu\n", addr);
|
// TODO size_t should be replaced by char * for pointer arithmetic
|
||||||
if ((addr + sizeof(t_block)) % 16 != 0) {
|
size_t addr = ((size_t)zone + sizeof(t_zone));
|
||||||
addr += 16 - ((addr + sizeof(t_block)) % 16);
|
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;
|
||||||
}
|
}
|
||||||
printf("addr %zu\n", addr);
|
|
||||||
*head = (t_block *)addr;
|
|
||||||
printf("addr of g_zones.tiny_zones : %p\n \
|
|
||||||
addr of *head %p\n \
|
|
||||||
sizeof tzone : %zu\n \
|
|
||||||
size of tblock %zu\n",
|
|
||||||
g_zones.tiny_zones,
|
|
||||||
*head,
|
|
||||||
sizeof(t_zone),
|
|
||||||
sizeof(t_block));
|
|
||||||
(*head)->size = size;
|
|
||||||
(*head)->free = 0;
|
|
||||||
(*head)->next = NULL;
|
|
||||||
return (void *)((char *)(*head) + sizeof(t_block));
|
|
||||||
}
|
}
|
||||||
else {
|
return NULL;
|
||||||
t_block *curr = *head;
|
}
|
||||||
while (curr->next) {
|
|
||||||
// todo check if free and defrag
|
t_zone *create_new_small_zone(void) {
|
||||||
curr = curr->next;
|
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));
|
||||||
}
|
}
|
||||||
printf("addr of curr %p\n \
|
else {
|
||||||
curr->size %zu\n", curr, curr->size);
|
while (curr->next) {
|
||||||
// TODO size_t should be replaced by char * for pointer arithmetic
|
// todo check if free and defrag
|
||||||
size_t addr = (size_t)curr + sizeof(t_block) + curr->size;
|
curr = curr->next;
|
||||||
printf("addr %zu\n", addr);
|
}
|
||||||
if ((addr + sizeof(t_block)) % 16 != 0) {
|
// TODO size_t should be replaced by char * for pointer arithmetic
|
||||||
addr += 16 - ((addr + sizeof(t_block)) % 16);
|
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;
|
||||||
}
|
}
|
||||||
printf("addr %zu\n", addr);
|
}
|
||||||
curr->next = (t_block *)addr;
|
return NULL;
|
||||||
curr = curr->next;
|
}
|
||||||
printf("addr of curr %p\n", curr);
|
|
||||||
|
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->size = size;
|
||||||
curr->free = 0;
|
curr->free = 0;
|
||||||
curr->next = NULL;
|
curr->next = NULL;
|
||||||
return (void *)((char *)curr + sizeof(t_block));
|
return (void *)((char *)curr + sizeof(t_block));
|
||||||
}
|
}
|
||||||
return NULL;
|
while (curr->next) {
|
||||||
}
|
curr = curr->next;
|
||||||
|
}
|
||||||
void *malloc_small(size_t size) {
|
// TODO protect mmap
|
||||||
(void)size;
|
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));
|
||||||
return NULL;
|
curr = curr->next;
|
||||||
}
|
curr->size = size;
|
||||||
|
curr->free = 0;
|
||||||
void *malloc_large(size_t size) {
|
curr->next = NULL;
|
||||||
(void)size;
|
return (void *)((char *)curr + sizeof(t_block));
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *ft_malloc(size_t size) {
|
void *ft_malloc(size_t size) {
|
||||||
pthread_mutex_lock(&g_malloc_mutex);
|
pthread_mutex_lock(&g_malloc_mutex);
|
||||||
void *ptr = NULL;
|
void *ptr = NULL;
|
||||||
if (size < g_zones.tiny_block_max_size) {
|
if (size < g_zones.tiny_block_max_size) {
|
||||||
printf("entering malloc_tiny\n");
|
|
||||||
ptr = malloc_tiny(size);
|
ptr = malloc_tiny(size);
|
||||||
} else if (size < g_zones.small_block_max_size) {
|
} else if (size < g_zones.small_block_max_size) {
|
||||||
ptr = malloc_small(size);
|
ptr = malloc_small(size);
|
||||||
} else {
|
} else {
|
||||||
ptr = malloc_large(size);
|
ptr = malloc_large(size);
|
||||||
}
|
}
|
||||||
write(1, "42 from malloc\n", 15);
|
|
||||||
pthread_mutex_unlock(&g_malloc_mutex);
|
pthread_mutex_unlock(&g_malloc_mutex);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue