8 #define CT_ASSERT(exp) { assert(exp); }
10 #define NEW(t) (t*) malloc(sizeof(t))
11 #define NEW_ARRAY(t,n) (t*) malloc(sizeof(t)*(n))
12 #define NEW_PTR_ARRAY(t,n) (t**) malloc(sizeof(t*)*(n))
15 // If available, use aligned_alloc for cache-line-aligned allocations. Otherwise
16 // fall back to plain malloc.
18 #define NEW_CACHE_ALIGNED(t,p) \
20 if (posix_memalign((void*) &(p), 64, (sizeof(t) + (sizeof(t) % 64 ? 64 - (sizeof(t) % 64) : 0))) != 0) (p) = 0; \
23 #define ALLOC_CACHE_ALIGNED(s,p) \
25 if (posix_memalign((void*) &(p), 64, (s + (s % 64 ? 64 - (s % 64) : 0))) != 0) (p) = 0; \
28 #define ZERO(p) memset(p, 0, sizeof(*p))
30 #define DEQ_DECLARE(i,d) typedef struct { \
37 #define DEQ_LINKS_N(n,t) t *prev##n; t *next##n
38 #define DEQ_LINKS(t) DEQ_LINKS_N(,t)
39 #define DEQ_EMPTY {0,0,0,0}
41 #define DEQ_INIT(d) do { (d).head = 0; (d).tail = 0; (d).scratch = 0; (d).size = 0; } while (0)
42 #define DEQ_IS_EMPTY(d) ((d).head == 0)
43 #define DEQ_ITEM_INIT_N(n,i) do { (i)->next##n = 0; (i)->prev##n = 0; } while(0)
44 #define DEQ_ITEM_INIT(i) DEQ_ITEM_INIT_N(,i)
45 #define DEQ_HEAD(d) ((d).head)
46 #define DEQ_TAIL(d) ((d).tail)
47 #define DEQ_SIZE(d) ((d).size)
48 #define DEQ_NEXT_N(n,i) (i)->next##n
49 #define DEQ_NEXT(i) DEQ_NEXT_N(,i)
50 #define DEQ_PREV_N(n,i) (i)->prev##n
51 #define DEQ_PREV(i) DEQ_PREV_N(,i)
52 #define DEQ_MOVE(d1,d2) do {d2 = d1; DEQ_INIT(d1);} while (0)
54 *@pre ptr points to first element of deq
55 *@post ptr points to first element of deq that passes test, or 0. Test should involve ptr.
57 #define DEQ_FIND_N(n,ptr,test) while((ptr) && !(test)) ptr = DEQ_NEXT_N(n,ptr);
58 #define DEQ_FIND(ptr,test) DEQ_FIND_N(,ptr,test)
60 #define DEQ_INSERT_HEAD_N(n,d,i) \
62 CT_ASSERT((i)->next##n == 0); \
63 CT_ASSERT((i)->prev##n == 0); \
65 (i)->next##n = (d).head; \
66 (d).head->prev##n = i; \
70 CT_ASSERT((d).size == 0); \
76 #define DEQ_INSERT_HEAD(d,i) DEQ_INSERT_HEAD_N(,d,i)
78 #define DEQ_INSERT_TAIL_N(n,d,i) \
80 CT_ASSERT((i)->next##n == 0); \
81 CT_ASSERT((i)->prev##n == 0); \
83 (i)->prev##n = (d).tail; \
84 (d).tail->next##n = i; \
88 CT_ASSERT((d).size == 0); \
94 #define DEQ_INSERT_TAIL(d,i) DEQ_INSERT_TAIL_N(,d,i)
96 #define DEQ_REMOVE_HEAD_N(n,d) \
98 CT_ASSERT((d).head); \
100 (d).scratch = (d).head; \
101 (d).head = (d).head->next##n; \
102 if ((d).head == 0) { \
104 CT_ASSERT((d).size == 1); \
106 (d).head->prev##n = 0; \
108 (d).scratch->next##n = 0; \
109 (d).scratch->prev##n = 0; \
112 #define DEQ_REMOVE_HEAD(d) DEQ_REMOVE_HEAD_N(,d)
114 #define DEQ_REMOVE_TAIL_N(n,d) \
116 CT_ASSERT((d).tail); \
118 (d).scratch = (d).tail; \
119 (d).tail = (d).tail->prev##n; \
120 if ((d).tail == 0) { \
122 CT_ASSERT((d).size == 1); \
124 (d).tail->next##n = 0; \
126 (d).scratch->next##n = 0; \
127 (d).scratch->prev##n = 0; \
130 #define DEQ_REMOVE_TAIL(d) DEQ_REMOVE_TAIL_N(,d)
132 #define DEQ_INSERT_AFTER_N(n,d,i,a) \
134 CT_ASSERT((i)->next##n == 0); \
135 CT_ASSERT((i)->prev##n == 0); \
138 (a)->next##n->prev##n = (i); \
141 (i)->next##n = (a)->next##n; \
142 (i)->prev##n = (a); \
143 (a)->next##n = (i); \
146 #define DEQ_INSERT_AFTER(d,i,a) DEQ_INSERT_AFTER_N(,d,i,a)
148 #define DEQ_REMOVE_N(n,d,i) \
151 (i)->next##n->prev##n = (i)->prev##n; \
153 (d).tail = (i)->prev##n; \
155 (i)->prev##n->next##n = (i)->next##n; \
157 (d).head = (i)->next##n; \
158 CT_ASSERT((d).size > 0); \
162 CT_ASSERT((d).size || (!(d).head && !(d).tail)); \
164 #define DEQ_REMOVE(d,i) DEQ_REMOVE_N(,d,i)
166 #define DEQ_APPEND_N(n,d1,d2) \
170 else if ((d2).head) { \
171 (d1).tail->next##n = (d2).head; \
172 (d2).head->prev##n = (d1).tail; \
173 (d1).tail = (d2).tail; \
174 (d1).size += (d2).size; \
178 #define DEQ_APPEND(d1,d2) DEQ_APPEND_N(,d1,d2)