This commit is contained in:
Guillem George 2025-11-07 23:29:21 +01:00
parent b4f942f678
commit 3a7a564bdf
9 changed files with 91 additions and 24 deletions

View file

@ -1,20 +1,29 @@
CC=gcc
CFLAGS=-std=c99 -pedantic -Werror -Wall -Wextra -Wvla -fvisibility=hidden -fPIC
CPPFLAGS= -D_DEFAULT_SOURCE
LDFLAGS= -shared -Wl --no-undefined
LDFLAGS= -shared -Wl,--no-undefined
LDLIBS=
SRCS=src/malloc.c src/helpers/helpers.c src/helpers/allocate.c
OBJS=${SRCS:.c=.o}
TST_OBJS = tests/test.o
TARGET=libmalloc.so
library: $(OBJS)
$(CC) -o $(TARGET) $^
$(CC) -o $(TARGET) $^ $(LDFLAGS)
debug: $(OBJS) $(TST_OBJS)
$(CC) -o $(TST_TARGET) $^
debug: CFLAGS += -g
debug: $(OBJS)
$(CC) -o $(TARGET) $^ $(LDFLAGS)
# test: LDLIBS += -lcriterion
test: CFLAGS = -g -L. -lmalloc -fPIC -fvisibility=hidden
test: library $(TST_OBJS)
$(CC) -o $(TST_TARGET) $^ $(LDLIBS)
check:
dash tests/test-cmd.sh
clean:
$(RM) *.o
$(RM) $(OBJS)
$(RM) $(TARGET)

BIN
malloc/library Executable file

Binary file not shown.

View file

@ -4,16 +4,17 @@
#include <sys/mman.h>
#include "helpers.h"
// c'est dangereux de pas s'i3lock
// coucou
void *allocate_block(struct bucket *biquette, int block_number)
{
if (block_number == -1)
return NULL;
// Update header
unsigned char byte_mask = 1 << ((block_number % 8) - 1);
unsigned char byte_mask = 1 << (8 - 1 - (block_number % 8));
biquette->alloc_blk_cnt++;
biquette->free_map[block_number / 8] &= byte_mask;
biquette->free_map[block_number / 8] |= byte_mask;
// Compute block address
return get_block(biquette, block_number);
@ -31,8 +32,8 @@ struct bucket *create_bucket(size_t min_alloc_size)
alloc_size = s2p(min_alloc_size);
// Get page
void *page =
mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, -1, 0);
void *page = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (page == NULL)
return NULL;
@ -41,6 +42,7 @@ struct bucket *create_bucket(size_t min_alloc_size)
struct bucket *header = page;
header->block_size = alloc_size;
header->alloc_blk_cnt = 0;
header->alloc_size = alloc_size;
memset(header->free_map, 0, FREE_LIST_SIZE);
return header;
@ -51,8 +53,26 @@ void free_block(void *ptr, struct bucket **list)
// Compute header location and block number
struct bucket *header = get_page_begin(ptr);
// Verify that header belongs to list
struct bucket *elt = *list;
int found = 0;
while (elt != NULL)
{
if (elt == header)
{
found = 1;
break;
}
elt = elt->next;
}
if (!found)
return;
// free in map and update size
int block_number; // ...
int block_number = get_block_number(header, ptr);
if (block_number == -1)
return;
unsigned char byte_mask = 1 << ((block_number % 8) - 1);
header->free_map[block_number / 8] &= ~byte_mask;
@ -65,6 +85,6 @@ void free_block(void *ptr, struct bucket **list)
if (header->alloc_blk_cnt == 0)
{
bucket_list_remove(list, header);
munmap(ptr, 1);
munmap(header, header->alloc_size);
}
}

View file

@ -1,10 +1,10 @@
#ifndef ALLOCATE_H
#define ALLOCATE_H
#include "helpers.h"
#include <stddef.h>
#include "helpers.h"
void *allocate_block(struct bucket *biquette, int block_number);
struct bucket *create_bucket(size_t min_alloc_size);
void bucket_append(struct bucket **head, struct bucket *elt);

View file

@ -21,7 +21,7 @@ size_t s2p(size_t s)
// (found __builtin_clzll but not sure of what it does)
// So here's the good old way
size_t n = 1;
size_t n = MIN_BLOCK_SIZE;
while (n < s)
{
n <<= 1;
@ -41,7 +41,7 @@ int find_free_block(struct bucket *buck)
// Test byte
for (unsigned j = 0; j < 8; j <<= 1)
{
if (map_byte & bit) // Test if free
if (map_byte ^ bit) // Test if free
return i * 8 + j;
bit <<= 1;
@ -51,6 +51,7 @@ int find_free_block(struct bucket *buck)
return -1;
}
// Computes the block address based on its position in the freemap
void *get_block(struct bucket *biquette, int block_number)
{
if (block_number == -1)
@ -60,6 +61,7 @@ void *get_block(struct bucket *biquette, int block_number)
return data_begin + (biquette->block_size * (block_number));
}
// Gets block position in the freemap based on its address
int get_block_number(struct bucket *biquette, void *block)
{
if (block == NULL || biquette == NULL)
@ -81,17 +83,20 @@ struct bucket *get_bucket(struct bucket *head, size_t size)
{
if (head->block_size >= size)
return head;
head = head->next;
}
return NULL;
}
// Computes the buckets first block address
void *get_data_begin(struct bucket *biquette)
{
// TODO alignment
return biquette + sizeof(struct bucket);
}
// Computes the beginning address of the page containing ptr
void *get_page_begin(void *ptr)
{
size_t quelenfer = ((size_t)ptr) & ~(PAGE_SIZE - 1);
@ -99,6 +104,7 @@ void *get_page_begin(void *ptr)
return pointeur_alacon + quelenfer;
}
// Appends a bucket address to the list pointed by head
void bucket_list_append(struct bucket **head, struct bucket *elt)
{
struct bucket *list_elt = *head;

View file

@ -3,7 +3,7 @@
// #define PAGE_SIZE sysconf(_SC_PAGE_SIZE)
#define PAGE_SIZE 4096
#define MIN_BLOCK_SIZE 8
#define MIN_BLOCK_SIZE 16
#define FREE_LIST_SIZE PAGE_SIZE / MIN_BLOCK_SIZE / sizeof(unsigned char)
#include <stddef.h>
@ -13,13 +13,16 @@
struct bucket
{
unsigned block_size;
unsigned char free_map[FREE_LIST_SIZE]; // Keeps track of allocations
unsigned char free_map[FREE_LIST_SIZE]; // Keeps track of allocations
// If block_size > MIN_BLOCK_SIZE
// It will use a consecutive
// representation
unsigned short alloc_blk_cnt; // Counts the number of allocated blocks
struct bucket *next;
size_t checksum;
size_t alloc_size;
unsigned short space1; //
unsigned int space2; // -> Both are used to align data on 16 bytes
};
#define BUCKET_SIZE PAGE_SIZE - sizeof(struct bucket)
@ -29,7 +32,8 @@ int find_free_block(struct bucket *buck);
struct bucket *get_bucket(struct bucket *head, size_t size);
void *get_data_begin(struct bucket *biquette);
void *get_page_begin(void *ptr);
void *get_block(struct bucket* biquette, int block_number);
void *get_block(struct bucket *biquette, int block_number);
int get_block_number(struct bucket *biquette, void *block);
void bucket_list_append(struct bucket **head, struct bucket *elt);
void bucket_list_remove(struct bucket **head, struct bucket *elt);

View file

@ -18,7 +18,7 @@ __attribute__((visibility("default"))) void *malloc(size_t size)
// Find adequate block
int block_number = find_free_block(buck);
if (block_number != -1)
return get_block(buck, block_number);
return allocate_block(buck, block_number);
else
{
// No free space -> loop
@ -27,8 +27,8 @@ __attribute__((visibility("default"))) void *malloc(size_t size)
}
buck = create_bucket(size);
bucket_append(&head, buck);
return get_data_begin(buck);
bucket_list_append(&head, buck);
return allocate_block(buck, 1);
}
__attribute__((visibility("default"))) void free(void *ptr)

3
malloc/tests/test-cmd.sh Executable file
View file

@ -0,0 +1,3 @@
#!/bi/sh
echo Hello world!

25
malloc/tests/test.c Normal file
View file

@ -0,0 +1,25 @@
// #include <criterion/criterion.h>
// #include <criterion/new/assert.h>
// TestSuite(Main);
// Test(Main, test1)
// {
// int *i = malloc(16);
// cr_assert(i != NULL);
// }
#include <stdlib.h>
int main(void)
{
int *test = malloc(8);
void *tes2 = malloc(8);
void *tes3 = malloc(32);
void *tes4 = malloc(64);
void *tes5 = malloc(128);
void *tes6 = malloc(256);
void *tes7 = malloc(512);
void *tes8 = malloc(4096);
void *tes9 = malloc(95956);
}