beginnings of binaryout
[henge/apc.git] / src / pagenode.h
1 #include <stdlib.h> //malloc
2
3 extern //apc.c
4 long sys_pagesize;
5
6 #define SYS_PAGESIZE (sys_pagesize)
7 #define NAME_PAGESIZE (APC_NAME_MAX * 1024)
8 #define PL_HEADERSIZE (sizeof(struct pagenode_header_t))
9 #define PL_HEADSIZE(_PL) (_PL.head->header.head - _PL.head->root)
10 #define PL_HEADMEM(_PL) (_PL.pagesize - PL_HEADERSIZE - PL_HEADSIZE(_PL))
11 #define struct_clear(_S) (memset((_S), 0, sizeof(*(_S))))
12 /* Memory allocation structures */
13 struct pagenode_t;
14 struct pagenode_header_t {
15 struct pagenode_t* next;
16 char* head;
17 };
18 struct pagenode_t {
19 struct pagenode_header_t header;
20 char root[];
21 };
22 struct pagelist_t {
23 struct pagenode_t* root, * head;
24 size_t pagesize;
25 };
26
27 static
28 void* stack_alloc(struct pagelist_t*, size_t);
29 static inline
30 void* pagelist_pop(struct pagelist_t*,size_t);
31 #define $($)#$
32 #define pagelist_alloc(pagelist) do { \
33 pagelist.head->header.next = (struct pagenode_t*) malloc(pagelist.pagesize); \
34 if (pagelist.head->header.next == NULL) \
35 eprintf("Memory allocation error\n"); \
36 struct_clear(pagelist.head->header.next); \
37 pagelist.head = pagelist.head->header.next; \
38 pagelist.head->header.head = pagelist.head->root; \
39 } while (0)
40 #define pagelist_init(pagelist,size) do { \
41 pagelist.pagesize = size; \
42 pagelist.root = (struct pagenode_t*) malloc(size); \
43 if (pagelist.root == NULL) \
44 eprintf("Memory allocation error\n"); \
45 struct_clear(pagelist.root); \
46 pagelist.head = pagelist.root; \
47 pagelist.head->header.head = pagelist.head->root; \
48 } while (0)
49 static
50 void pagenode_free(struct pagenode_t*);
51
52 static inline
53 void* pagelist_pop
54 ( struct pagelist_t* pagelist,
55 size_t size
56 )
57 { size_t headsize = PL_HEADSIZE((*pagelist));
58 if (!headsize)
59 { free(pagelist->head);
60 pagelist->head = pagelist->root;
61 while (pagelist->head->header.next != NULL)
62 pagelist->head = pagelist->head->header.next;
63 }
64 if (headsize < size)
65 eprintf("Attempted to pop unaligned value from pagelist\n");
66 pagelist->head->header.head -= size;
67 return pagelist->head->header.head;
68 }
69
70 /* Recursively clean pagenode linked list, freeing last first */
71 static
72 void pagenode_free
73 ( struct pagenode_t* pagenode )
74 { if (pagenode->header.next != NULL)
75 pagenode_free(pagenode->header.next);
76 free(pagenode);
77 }
78 static
79 void* stack_alloc
80 ( struct pagelist_t* pagelist,
81 size_t bytes )
82 { void* p;
83 if (PL_HEADMEM((*pagelist)) < bytes)
84 pagelist_alloc((*pagelist));
85 p = pagelist->head->header.head;
86 pagelist->head->header.head += bytes;
87 return p;
88 }