--- /dev/null
+#include <stdlib.h> //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;
+}