malloc moi le fion
This commit is contained in:
parent
de0af4715b
commit
13b314f8f5
4 changed files with 66 additions and 31 deletions
|
|
@ -12,7 +12,7 @@ void *allocate_block(struct bucket *biquette, int block_number)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Update header
|
// Update header
|
||||||
unsigned char byte_mask = 1 << (8 - 1 - (block_number % 8));
|
unsigned char byte_mask = 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;
|
||||||
|
|
||||||
|
|
@ -22,17 +22,24 @@ 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)
|
||||||
{
|
{
|
||||||
// Round up
|
size_t page_alloc_size;
|
||||||
size_t alloc_size;
|
size_t block_alloc_size;
|
||||||
|
|
||||||
if (min_alloc_size > PAGE_SIZE - sizeof(struct bucket))
|
if (min_alloc_size > PAGE_SIZE - sizeof(struct bucket))
|
||||||
|
{
|
||||||
// Huge page
|
// Huge page
|
||||||
alloc_size = min_alloc_size;
|
page_alloc_size = min_alloc_size + sizeof(struct bucket);
|
||||||
|
block_alloc_size = page_alloc_size;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
// Regular page
|
// Regular page
|
||||||
alloc_size = s2p(min_alloc_size);
|
page_alloc_size = PAGE_SIZE;
|
||||||
|
block_alloc_size = s2p(min_alloc_size);
|
||||||
|
}
|
||||||
|
|
||||||
// Get page
|
// Get page
|
||||||
void *page = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE,
|
void *page = mmap(NULL, page_alloc_size, PROT_READ | PROT_WRITE,
|
||||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||||
|
|
||||||
if (page == NULL)
|
if (page == NULL)
|
||||||
|
|
@ -40,9 +47,9 @@ struct bucket *create_bucket(size_t min_alloc_size)
|
||||||
|
|
||||||
// Init bucket
|
// Init bucket
|
||||||
struct bucket *header = page;
|
struct bucket *header = page;
|
||||||
header->block_size = alloc_size;
|
header->block_size = block_alloc_size;
|
||||||
header->alloc_blk_cnt = 0;
|
header->alloc_blk_cnt = 0;
|
||||||
header->alloc_size = alloc_size;
|
header->alloc_size = page_alloc_size;
|
||||||
memset(header->free_map, 0, FREE_LIST_SIZE);
|
memset(header->free_map, 0, FREE_LIST_SIZE);
|
||||||
|
|
||||||
return header;
|
return header;
|
||||||
|
|
@ -73,14 +80,11 @@ void free_block(void *ptr, struct bucket **list)
|
||||||
if (block_number == -1)
|
if (block_number == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned char byte_mask = 1 << ((block_number % 8) - 1);
|
unsigned char byte_mask = 1 << ((block_number % 8));
|
||||||
header->free_map[block_number / 8] &= ~byte_mask;
|
header->free_map[block_number / 8] &= ~byte_mask;
|
||||||
|
header->alloc_blk_cnt--;
|
||||||
|
|
||||||
// Huge page
|
// Huge page
|
||||||
if (header->block_size > BUCKET_SIZE)
|
|
||||||
// Delete bucket
|
|
||||||
header->alloc_blk_cnt = 0;
|
|
||||||
|
|
||||||
// free bucket if necessary
|
// free bucket if necessary
|
||||||
if (header->alloc_blk_cnt == 0)
|
if (header->alloc_blk_cnt == 0)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -32,19 +32,29 @@ size_t s2p(size_t s)
|
||||||
|
|
||||||
int find_free_block(struct bucket *buck)
|
int find_free_block(struct bucket *buck)
|
||||||
{
|
{
|
||||||
unsigned maplength = PAGE_SIZE / buck->block_size / 8;
|
// Huge pages
|
||||||
// for each block
|
if (buck->block_size > BUCKET_SIZE)
|
||||||
|
{
|
||||||
|
// Check block 0
|
||||||
|
if (!(buck->free_map[0] & (1 << 0)))
|
||||||
|
return 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t num_blocks_in_page = (PAGE_SIZE - sizeof(struct bucket)) / buck->block_size;
|
||||||
|
size_t maplength = (num_blocks_in_page + 7) / 8; // +7 for ceiling division (oui c'est moche mais ça marche)
|
||||||
|
|
||||||
|
// Foreach byte
|
||||||
for (unsigned i = 0; i < maplength; i++)
|
for (unsigned i = 0; i < maplength; i++)
|
||||||
{
|
{
|
||||||
unsigned char map_byte = buck->free_map[i];
|
unsigned char map_byte = buck->free_map[i];
|
||||||
unsigned char bit = 1;
|
if (map_byte == 0xFF) // Skip if used
|
||||||
// Test byte
|
continue;
|
||||||
for (unsigned j = 0; j < 8; j <<= 1)
|
|
||||||
{
|
|
||||||
if (map_byte ^ bit) // Test if free
|
|
||||||
return i * 8 + j;
|
|
||||||
|
|
||||||
bit <<= 1;
|
for (unsigned j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
if ((i * 8 + j) < num_blocks_in_page && !(map_byte & (1 << j))) // Check if free
|
||||||
|
return i * 8 + j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,11 +78,20 @@ int get_block_number(struct bucket *biquette, void *block)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
char *block_nul = block;
|
char *block_nul = block;
|
||||||
void *biquetteounette = biquette;
|
char* bibiche = get_data_begin(biquette); // Célèbre bar Capcinois, venez à l'occasion
|
||||||
char *biquette_cherie = biquetteounette;
|
|
||||||
|
return (block_nul - bibiche) / biquette->block_size;
|
||||||
|
|
||||||
|
// Au revoir mes belles
|
||||||
|
// Vous manquerez à papa
|
||||||
|
// (mais fallait marcher, là ça marche pas)
|
||||||
|
|
||||||
|
// void *biquetteounette = biquette;
|
||||||
|
// char *biquette_cherie = biquetteounette;
|
||||||
|
|
||||||
|
// return (block_nul - biquette_cherie - sizeof(struct bucket))
|
||||||
|
// / biquette->block_size;
|
||||||
|
|
||||||
return (block_nul - biquette_cherie - sizeof(struct bucket))
|
|
||||||
/ biquette->block_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets a bucket with at least a block_size of size
|
// Gets a bucket with at least a block_size of size
|
||||||
|
|
@ -93,7 +112,9 @@ struct bucket *get_bucket(struct bucket *head, size_t size)
|
||||||
// Computes the buckets first block address
|
// Computes the buckets first block address
|
||||||
void *get_data_begin(struct bucket *biquette)
|
void *get_data_begin(struct bucket *biquette)
|
||||||
{
|
{
|
||||||
return biquette + sizeof(struct bucket);
|
void* maisqueltrucdemerde = biquette;
|
||||||
|
char* biquettas = maisqueltrucdemerde;
|
||||||
|
return biquettas + sizeof(struct bucket);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Computes the beginning address of the page containing ptr
|
// Computes the beginning address of the page containing ptr
|
||||||
|
|
@ -130,7 +151,7 @@ void bucket_list_remove(struct bucket **head, struct bucket *elt)
|
||||||
|
|
||||||
if (*head == elt)
|
if (*head == elt)
|
||||||
{
|
{
|
||||||
*head = NULL;
|
*head = elt->next;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ __attribute__((visibility("default"))) void *malloc(size_t size)
|
||||||
|
|
||||||
buck = create_bucket(size);
|
buck = create_bucket(size);
|
||||||
bucket_list_append(&head, buck);
|
bucket_list_append(&head, buck);
|
||||||
return allocate_block(buck, 1);
|
int first_free_buche = find_free_block(buck); // De noel (pas la mienne)
|
||||||
|
return allocate_block(buck, first_free_buche);
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((visibility("default"))) void free(void *ptr)
|
__attribute__((visibility("default"))) void free(void *ptr)
|
||||||
|
|
@ -56,6 +57,8 @@ __attribute__((visibility("default"))) void *realloc(void *ptr, size_t size)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
void *new_ptr = malloc(size);
|
void *new_ptr = malloc(size);
|
||||||
|
if (new_ptr == NULL)
|
||||||
|
return NULL;
|
||||||
memcpy(new_ptr, ptr, header->block_size);
|
memcpy(new_ptr, ptr, header->block_size);
|
||||||
free(ptr);
|
free(ptr);
|
||||||
return new_ptr;
|
return new_ptr;
|
||||||
|
|
@ -66,7 +69,14 @@ __attribute__((visibility("default"))) void *realloc(void *ptr, size_t size)
|
||||||
|
|
||||||
__attribute__((visibility("default"))) void *calloc(size_t nmemb, size_t size)
|
__attribute__((visibility("default"))) void *calloc(size_t nmemb, size_t size)
|
||||||
{
|
{
|
||||||
char *res = malloc(nmemb * size);
|
// Check overflow
|
||||||
|
size_t c;
|
||||||
|
if (__builtin_mul_overflow(nmemb, size, &c))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
char *res = malloc(c);
|
||||||
|
if (res == NULL)
|
||||||
|
return NULL;
|
||||||
memset(res, 0, nmemb * size);
|
memset(res, 0, nmemb * size);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ LD_PRELOAD=./libmalloc.so ls 1> /dev/null
|
||||||
check
|
check
|
||||||
LD_PRELOAD=./libmalloc.so ip a 1> /dev/null
|
LD_PRELOAD=./libmalloc.so ip a 1> /dev/null
|
||||||
check
|
check
|
||||||
LD_PRELOAD=./libmalloc.so grep 1> /dev/null
|
LD_PRELOAD=./libmalloc.so grep --help 1> /dev/null
|
||||||
check
|
check
|
||||||
LD_PRELOAD=./libmalloc.so find 1> /dev/null
|
LD_PRELOAD=./libmalloc.so find 1> /dev/null
|
||||||
check
|
check
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue