Align free list nodes (#101)

This commit is contained in:
Alex Kotov 2022-06-27 14:54:16 +03:00 committed by GitHub
parent febd43c987
commit 6d5c3740a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 10 deletions

View File

@ -12,15 +12,16 @@ extern "C" {
#include <stddef.h>
typedef struct KernAux_FreeList_Node {
void *KERNAUX_PRIVATE_FIELD(orig_ptr);
struct KernAux_FreeList_Node *KERNAUX_PRIVATE_FIELD(next);
struct KernAux_FreeList_Node *KERNAUX_PRIVATE_FIELD(prev);
size_t KERNAUX_PRIVATE_FIELD(size);
char *KERNAUX_PRIVATE_FIELD(block);
size_t KERNAUX_PRIVATE_FIELD(size);
char *KERNAUX_PRIVATE_FIELD(block);
} *KernAux_FreeList_Node;
typedef struct KernAux_FreeList {
struct KernAux_Malloc malloc;
KernAux_Mutex KERNAUX_PRIVATE_FIELD(mutex);
KernAux_Mutex KERNAUX_PRIVATE_FIELD(mutex);
KernAux_FreeList_Node KERNAUX_PRIVATE_FIELD(head);
} *KernAux_FreeList;

View File

@ -23,10 +23,10 @@
#define MIN_ZONE_SIZE (2 * NODE_HEADER_SIZE)
#define MIN_SPLIT_SIZE (NODE_HEADER_SIZE + 16)
//#define ALIGN_MASK(align) ((align) - 1) // align should be a power of 2
//#define ALIGN_UP(val, align) (((val) + ALIGN_MASK(align)) & ~ALIGN_MASK(align))
#define ALIGN_MASK(align) ((align) - 1) // align should be a power of 2
#define ALIGN_UP(val, align) (((val) + ALIGN_MASK(align)) & ~ALIGN_MASK(align))
//#define PTR_ALIGNMENT (sizeof(void*)) // TODO: align node to this value
#define PTR_ALIGNMENT (sizeof(void*))
#define LOCK(free_list) \
do { \
@ -90,7 +90,9 @@ void KernAux_FreeList_add_zone(
LOCK(free_list);
KernAux_FreeList_Node new_node = ptr;
KernAux_FreeList_Node new_node =
(KernAux_FreeList_Node)ALIGN_UP((uintptr_t)ptr, PTR_ALIGNMENT);
new_node->orig_ptr = ptr;
new_node->size = size;
KernAux_FreeList_Node prev_node = NULL;
@ -159,7 +161,7 @@ block_added:
UNLOCK(free_list);
}
void *KernAux_FreeList_malloc(void *const malloc, const size_t size)
void *KernAux_FreeList_malloc(void *const malloc, size_t size)
{
const KernAux_FreeList free_list = malloc;
KERNAUX_ASSERT(free_list);
@ -167,6 +169,8 @@ void *KernAux_FreeList_malloc(void *const malloc, const size_t size)
LOCK(free_list);
size = ALIGN_UP(size, PTR_ALIGNMENT);
KernAux_FreeList_Node node = NULL;
for (
@ -183,9 +187,18 @@ void *KernAux_FreeList_malloc(void *const malloc, const size_t size)
if (node) {
// Can we split the block?
if (node->size - size >= MIN_SPLIT_SIZE) {
node->size = NODE_HEADER_SIZE + size;
KernAux_FreeList_Node new_node =
(KernAux_FreeList_Node)(((uintptr_t)&node->block) + size);
node->size = NODE_HEADER_SIZE + size;
KERNAUX_ASSERT(
((uintptr_t)new_node)
==
ALIGN_UP((uintptr_t)new_node, PTR_ALIGNMENT)
);
new_node->orig_ptr = new_node;
new_node->size = node->size - size - NODE_HEADER_SIZE;
KernAux_FreeList_insert(free_list, new_node, node, node->next);
}
@ -240,7 +253,9 @@ void KernAux_FreeList_defrag(const KernAux_FreeList free_list)
) {
const KernAux_FreeList_Node node = item_node->prev;
if (!node) continue;
if (((uintptr_t)node) + node->size != (uintptr_t)item_node) continue;
if (((uintptr_t)node) + node->size != (uintptr_t)item_node->orig_ptr) {
continue;
}
node->size += item_node->size;
KernAux_FreeList_remove(free_list, item_node);