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 CC=gcc
CFLAGS=-std=c99 -pedantic -Werror -Wall -Wextra -Wvla -fvisibility=hidden -fPIC CFLAGS=-std=c99 -pedantic -Werror -Wall -Wextra -Wvla -fvisibility=hidden -fPIC
CPPFLAGS= -D_DEFAULT_SOURCE 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 SRCS=src/malloc.c src/helpers/helpers.c src/helpers/allocate.c
OBJS=${SRCS:.c=.o} OBJS=${SRCS:.c=.o}
TST_OBJS = tests/test.o
TARGET=libmalloc.so TARGET=libmalloc.so
library: $(OBJS) library: $(OBJS)
$(CC) -o $(TARGET) $^ $(CC) -o $(TARGET) $^ $(LDFLAGS)
debug: $(OBJS) $(TST_OBJS) debug: CFLAGS += -g
$(CC) -o $(TST_TARGET) $^ 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: check:
dash tests/test-cmd.sh
clean: clean:
$(RM) *.o $(RM) $(OBJS)
$(RM) $(TARGET) $(RM) $(TARGET)

BIN
malloc/library Executable file

Binary file not shown.

View file

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

View file

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

View file

@ -3,7 +3,7 @@
// #define PAGE_SIZE sysconf(_SC_PAGE_SIZE) // #define PAGE_SIZE sysconf(_SC_PAGE_SIZE)
#define PAGE_SIZE 4096 #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) #define FREE_LIST_SIZE PAGE_SIZE / MIN_BLOCK_SIZE / sizeof(unsigned char)
#include <stddef.h> #include <stddef.h>
@ -19,7 +19,10 @@ struct bucket
// representation // representation
unsigned short alloc_blk_cnt; // Counts the number of allocated blocks unsigned short alloc_blk_cnt; // Counts the number of allocated blocks
struct bucket *next; 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) #define BUCKET_SIZE PAGE_SIZE - sizeof(struct bucket)
@ -30,6 +33,7 @@ struct bucket *get_bucket(struct bucket *head, size_t size);
void *get_data_begin(struct bucket *biquette); void *get_data_begin(struct bucket *biquette);
void *get_page_begin(void *ptr); 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_append(struct bucket **head, struct bucket *elt);
void bucket_list_remove(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 // Find adequate block
int block_number = find_free_block(buck); int block_number = find_free_block(buck);
if (block_number != -1) if (block_number != -1)
return get_block(buck, block_number); return allocate_block(buck, block_number);
else else
{ {
// No free space -> loop // No free space -> loop
@ -27,8 +27,8 @@ __attribute__((visibility("default"))) void *malloc(size_t size)
} }
buck = create_bucket(size); buck = create_bucket(size);
bucket_append(&head, buck); bucket_list_append(&head, buck);
return get_data_begin(buck); return allocate_block(buck, 1);
} }
__attribute__((visibility("default"))) void free(void *ptr) __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);
}