Browse Source

Added some of allocator

tree_alloc
Thomas Johnson 1 year ago
parent
commit
cead24e00f
  1. 8
      allocator_internal.h
  2. 21
      tree_alloc.c
  3. 14
      util.c

8
allocator_internal.h

@ -17,6 +17,12 @@ typedef struct Arena {
// All three of these types should be memory-compatible with each other
// Before I forget to write it down: It is assumed that the beginning of every allocation region (or
// free space region) is aligned to the alignment of all three of these types (or WatermarkAlloc since
// it has at least all the fields of the other one). This allows for the allocation record to appear
// at the beginning of the region and still be aligned. As a consequence, all sizes are a multiple of
// the alignment.
typedef struct TreeAlloc {
char type; // Should be RT_TREE_NODE
struct TreeAlloc *parent;
@ -48,6 +54,8 @@ typedef struct WatermarkAlloc {
} WatermarkAlloc;
void* align_after(void* address, uintptr_t align);
uintptr_t lcm(uintptr_t a, uintptr_t b);
uintptr_t gcd(uintptr_t a, uintptr_t b);
TreeAlloc *insert_node_at(void *address, uintptr_t padding, uintptr_t align, uintptr_t size);
TreeAlloc *search_by_address(TreeAlloc *root, void *address);
TreeAlloc *search_by_size(TreeAlloc *root, uintptr_t padding, uintptr_t align, uintptr_t size);

21
tree_alloc.c

@ -159,11 +159,28 @@ void unalloc(Arena *arena, void *addr) {
insert_left((TreeAlloc**) &arena->root_freespace, (TreeAlloc*) start, insert_point);
}
}
// TODO
}
void *alloc(Arena arena, uintptr_t size, uintptr_t align) {
// TODO
if (arena->root_freespace == NULL) {
// TODO: handle out-of-memory
} else {
uintptr_t actual_align = lcm(alignof(WatermarkAlloc), align);
TreeAlloc *insert_point = search_by_size(arena->root_freespace, sizeof(TreeAlloc), actual_align, size);
if (insert_point == NULL) {
// TODO: handle memory fragmentation (or OOM)
}
remove_node(&arena->root_freespace, insert_point);
true_end = align_after(align_after(insert_point + sizeof(TreeAlloc), actual_align) + size, alignof(WatermarkAlloc));
// The size of the
uintptr_t new_size = true_end - insert_point;
uintptr_t new_free_size = insert_point.size - new_size;
if (new_free_size < sizeof(FreeSpace)) {
// TODO: Handle insufficient size for the new free region (by not having one)
} else {
// TODO: Add free region and allocation record
}
}
return NULL;
}

14
util.c

@ -11,3 +11,17 @@ void* align_after(void* address, int align) {
}
}
uintptr_t gcd(uintptr_t a, uintptr_t b) {
if (b > a) {
return gcd(b, a);
}
if (b == 0) {
return a;
}
return gcd(b, a % b);
}
uintptr_t lcm(uintptr_t a, uintptr_t b) {
return (a / gcd(a, b)) * b;
}
Loading…
Cancel
Save