backup
This commit is contained in:
parent
b4f942f678
commit
3a7a564bdf
9 changed files with 91 additions and 24 deletions
|
|
@ -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
BIN
malloc/library
Executable file
Binary file not shown.
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -29,7 +32,8 @@ int find_free_block(struct bucket *buck);
|
||||||
struct bucket *get_bucket(struct bucket *head, size_t size);
|
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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
3
malloc/tests/test-cmd.sh
Executable file
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bi/sh
|
||||||
|
|
||||||
|
echo Hello world!
|
||||||
25
malloc/tests/test.c
Normal file
25
malloc/tests/test.c
Normal 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);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue