#include "rt_alloc.h" #define ALLOCATOR_PAGE_SIZE (4096) /* Simple / Static Allocator */ void* salloc_alloc(int size) { // TODO do some trace return rt._malloc(size); } void* salloc_realloc(void* ptr, int size) { return rt._realloc(ptr, size); } void salloc_free(void* ptr) { // TODO do some trace rt._free(ptr); } /* Fixed Allocator */ #define PAGE_ALIGN(size) (((size) + ALLOCATOR_PAGE_SIZE -1) & ~(ALLOCATOR_PAGE_SIZE-1)) void falloc_init(fixed_alloc_t* fa, int fixed_size, int init_blocks) { fa->free_list = NULL; fa->page_list = NULL; // 确保块大小至少能存放指针(用于空闲链表) const int min_size = sizeof(void*); fa->block_size = (fixed_size < min_size) ? min_size : (fixed_size + 15) & ~15; // 16字节对齐 // 计算每页块数(优化缓存利用率) const int page_size = ALLOCATOR_PAGE_SIZE - sizeof(void*); fa->blocks_per_page = page_size / fa->block_size; // TODO copy paste 需要使用函数抽象 申请过程 // 预分配初始页 void* page = salloc_alloc(PAGE_ALIGN(fa->block_size * init_blocks)); unsigned char* p = (unsigned char*)page; for (int i = 0; i < init_blocks; ++i) { void** block = (void**)p; *block = fa->free_list; fa->free_list = block; p += fa->block_size; } *(void**)page = fa->page_list; fa->page_list = page; } void* falloc_alloc(fixed_alloc_t* fa) { if (!fa->free_list) { // 分配新页(带页头保存链表指针) void* page = salloc_alloc(ALLOCATOR_PAGE_SIZE); unsigned char* p = (unsigned char*)page + sizeof(void*); // 链接新页块到空闲链表 for (int i = 0; i < fa->blocks_per_page; ++i) { void** block = (void**)p; *block = fa->free_list; fa->free_list = block; p += fa->block_size; } *(void**)page = fa->page_list; fa->page_list = page; } void* block = fa->free_list; fa->free_list = *(void**)block; return (void*)((unsigned char*)block + sizeof(void*)); // 跳过链表指针 } void falloc_free(fixed_alloc_t* fa, void* ptr) { if (!fa || !ptr) return; void** block = (void**)((u8_t*)ptr - sizeof(void*)); *block = fa->free_list; fa->free_list = block; } void falloc_destroy(fixed_alloc_t* fa) { if (!fa) return; // 逆向释放所有内存页(保持地址连续性) void* current_page = fa->page_list; while (current_page) { void* next_page = *(void**)current_page; // 页头保存了链表指针 salloc_free(current_page); current_page = next_page; } // 防御性清零(防止悬垂指针) fa->free_list = NULL; fa->blocks_per_page = 0; fa->block_size = 0; fa->page_list = NULL; } /* Long Allocator */ void lalloc_init(long_alloc_t* la) { la->current = NULL; la->block_size = ALLOCATOR_PAGE_SIZE; // 初始块大小 } void* lalloc_alloc(long_alloc_t* la, int size) { size = (size + 15) & ~15; // 16字节对齐 if (!la->current || (la->current->used + size) > la->block_size) { int new_size = la->block_size; if (new_size < size + sizeof(long_block_t)) new_size = size + sizeof(long_block_t); long_block_t* new_block = (long_block_t*)salloc_alloc(new_size); new_block->next = la->current; new_block->used = sizeof(long_block_t); la->current = new_block; la->block_size = new_size; } void* ptr = (unsigned char*)la->current + la->current->used; la->current->used += size; return ptr; } void lalloc_destroy(long_alloc_t* la) { while (la->current) { long_block_t* prev = la->current->next; salloc_free(la->current); la->current = prev; } }