mirror of
https://github.com/tailix/libkernaux.git
synced 2025-03-17 17:14:00 -04:00
Align free list nodes (#101)
This commit is contained in:
parent
febd43c987
commit
6d5c3740a9
2 changed files with 26 additions and 10 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue