#include //malloc extern //apc.c long sys_pagesize; #define SYS_PAGESIZE (sys_pagesize) #define NAME_PAGESIZE (APC_NAME_MAX * 1024) #define PL_HEADERSIZE (sizeof(struct pagenode_header_t)) #define PL_HEADSIZE(_PL) (_PL.head->header.head - _PL.head->root) #define PL_HEADMEM(_PL) (_PL.pagesize - PL_HEADERSIZE - PL_HEADSIZE(_PL)) #define struct_clear(_S) (memset((_S), 0, sizeof(*(_S)))) /* Memory allocation structures */ struct pagenode_t; struct pagenode_header_t { struct pagenode_t* next; char* head; }; struct pagenode_t { struct pagenode_header_t header; char root[]; }; struct pagelist_t { struct pagenode_t* root, * head; size_t pagesize; }; static void* stack_alloc(struct pagelist_t*, size_t); static inline void* pagelist_pop(struct pagelist_t*,size_t); #define $($)#$ #define pagelist_alloc(pagelist) do { \ pagelist.head->header.next = (struct pagenode_t*) malloc(pagelist.pagesize); \ if (pagelist.head->header.next == NULL) \ eprintf("Memory allocation error\n"); \ struct_clear(pagelist.head->header.next); \ pagelist.head = pagelist.head->header.next; \ pagelist.head->header.head = pagelist.head->root; \ } while (0) #define pagelist_init(pagelist,size) do { \ pagelist.pagesize = size; \ pagelist.root = (struct pagenode_t*) malloc(size); \ if (pagelist.root == NULL) \ eprintf("Memory allocation error\n"); \ struct_clear(pagelist.root); \ pagelist.head = pagelist.root; \ pagelist.head->header.head = pagelist.head->root; \ } while (0) static void pagenode_free(struct pagenode_t*); static inline void* pagelist_pop ( struct pagelist_t* pagelist, size_t size ) { size_t headsize = PL_HEADSIZE((*pagelist)); if (!headsize) { free(pagelist->head); pagelist->head = pagelist->root; while (pagelist->head->header.next != NULL) pagelist->head = pagelist->head->header.next; } if (headsize < size) eprintf("Attempted to pop unaligned value from pagelist\n"); pagelist->head->header.head -= size; return pagelist->head->header.head; } /* Recursively clean pagenode linked list, freeing last first */ static void pagenode_free ( struct pagenode_t* pagenode ) { if (pagenode->header.next != NULL) pagenode_free(pagenode->header.next); free(pagenode); } static void* stack_alloc ( struct pagelist_t* pagelist, size_t bytes ) { void* p; if (PL_HEADMEM((*pagelist)) < bytes) pagelist_alloc((*pagelist)); p = pagelist->head->header.head; pagelist->head->header.head += bytes; return p; }