#ifndef ALLOCATOR_INTERNAL_H #define ALLOCATOR_INTERNAL_H #include // No enum because these need to be 1 byte const char RT_FREESPACE = 0; const char RT_TREE_NODE = 1; const char RT_WATERMARK = 2; const char COLOR_RED = 0; const char COLOR_BLACK = 1; const uintptr_t MIN_NEW_MEM_SIZE = 4096; typedef struct Arena { struct FreeSpace *root_freespace; struct TreeAlloc *root_treealloc; void *(*get_new_region)(uintptr_t); void (*error)(char*); } 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 char color; struct TreeAlloc *parent; struct TreeAlloc *left; struct TreeAlloc *right; uintptr_t size; struct TreeAlloc *before; struct TreeAlloc *after; } TreeAlloc; typedef struct FreeSpace { char type; // Should be RT_FREESPACE char color; struct FreeSpace *parent; struct FreeSpace *left; struct FreeSpace *right; uintptr_t size; } FreeSpace; typedef struct WatermarkAlloc { char type; // Should be RT_WATERMARK char color; struct TreeAlloc *parent; struct TreeAlloc *left; struct TreeAlloc *right; uintptr_t size; struct TreeAlloc *before; struct TreeAlloc *after; int num_allocs; void *next_alloc; } 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 *search_by_address(TreeAlloc *root, void *address); TreeAlloc *search_by_size(TreeAlloc *root, uintptr_t padding, uintptr_t align, uintptr_t size); TreeAlloc *get_sibling(TreeAlloc *p, TreeAlloc *ta); void rotate_left(TreeAlloc **root_ptr, TreeAlloc *ta); void rotate_right(TreeAlloc **root_ptr, TreeAlloc *ta); void repair_tree_after_insert(TreeAlloc **root_ptr, TreeAlloc *ta); void remove_node(TreeAlloc** root_ptr, TreeAlloc* node); void insert_singleton(TreeAlloc **root_ptr, TreeAlloc *to_insert); void insert_right(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* after); void insert_left(TreeAlloc** root_ptr, TreeAlloc* to_insert, TreeAlloc* before); void unalloc(Arena *arena, void *addr); void *alloc(Arena *arena, uintptr_t size, uintptr_t align); #endif