8 #define CT_ASSERT(exp) \
11 #define NEW(t) (t *)malloc(sizeof(t))
12 #define NEW_ARRAY(t, n) (t *)malloc(sizeof(t) * (n))
13 #define NEW_PTR_ARRAY(t, n) (t **)malloc(sizeof(t *) * (n))
16 // If available, use aligned_alloc for cache-line-aligned allocations. Otherwise
17 // fall back to plain malloc.
19 #define NEW_CACHE_ALIGNED(t, p) \
23 (sizeof(t) + (sizeof(t) % 64 ? 64 - (sizeof(t) % 64) : 0))) != 0) \
27 #define ALLOC_CACHE_ALIGNED(s, p) \
29 if (posix_memalign((void *)&(p), 64, \
30 (s + (s % 64 ? 64 - (s % 64) : 0))) != 0) \
34 #define ZERO(p) memset(p, 0, sizeof(*p))
36 #define DEQ_DECLARE(i, d) \
44 #define DEQ_LINKS_N(n, t) \
47 #define DEQ_LINKS(t) DEQ_LINKS_N(, t)
58 #define DEQ_IS_EMPTY(d) ((d).head == 0)
59 #define DEQ_ITEM_INIT_N(n, i) \
64 #define DEQ_ITEM_INIT(i) DEQ_ITEM_INIT_N(, i)
65 #define DEQ_HEAD(d) ((d).head)
66 #define DEQ_TAIL(d) ((d).tail)
67 #define DEQ_SIZE(d) ((d).size)
68 #define DEQ_NEXT_N(n, i) (i)->next##n
69 #define DEQ_NEXT(i) DEQ_NEXT_N(, i)
70 #define DEQ_PREV_N(n, i) (i)->prev##n
71 #define DEQ_PREV(i) DEQ_PREV_N(, i)
72 #define DEQ_MOVE(d1, d2) \
78 *@pre ptr points to first element of deq
79 *@post ptr points to first element of deq that passes test, or 0. Test should
82 #define DEQ_FIND_N(n, ptr, test) \
83 while ((ptr) && !(test)) \
84 ptr = DEQ_NEXT_N(n, ptr);
85 #define DEQ_FIND(ptr, test) DEQ_FIND_N(, ptr, test)
87 #define DEQ_INSERT_HEAD_N(n, d, i) \
89 CT_ASSERT((i)->next##n == 0); \
90 CT_ASSERT((i)->prev##n == 0); \
92 (i)->next##n = (d).head; \
93 (d).head->prev##n = i; \
97 CT_ASSERT((d).size == 0); \
103 #define DEQ_INSERT_HEAD(d, i) DEQ_INSERT_HEAD_N(, d, i)
105 #define DEQ_INSERT_TAIL_N(n, d, i) \
107 CT_ASSERT((i)->next##n == 0); \
108 CT_ASSERT((i)->prev##n == 0); \
110 (i)->prev##n = (d).tail; \
111 (d).tail->next##n = i; \
115 CT_ASSERT((d).size == 0); \
121 #define DEQ_INSERT_TAIL(d, i) DEQ_INSERT_TAIL_N(, d, i)
123 #define DEQ_REMOVE_HEAD_N(n, d) \
125 CT_ASSERT((d).head); \
127 (d).scratch = (d).head; \
128 (d).head = (d).head->next##n; \
129 if ((d).head == 0) { \
131 CT_ASSERT((d).size == 1); \
133 (d).head->prev##n = 0; \
135 (d).scratch->next##n = 0; \
136 (d).scratch->prev##n = 0; \
139 #define DEQ_REMOVE_HEAD(d) DEQ_REMOVE_HEAD_N(, d)
141 #define DEQ_REMOVE_TAIL_N(n, d) \
143 CT_ASSERT((d).tail); \
145 (d).scratch = (d).tail; \
146 (d).tail = (d).tail->prev##n; \
147 if ((d).tail == 0) { \
149 CT_ASSERT((d).size == 1); \
151 (d).tail->next##n = 0; \
153 (d).scratch->next##n = 0; \
154 (d).scratch->prev##n = 0; \
157 #define DEQ_REMOVE_TAIL(d) DEQ_REMOVE_TAIL_N(, d)
159 #define DEQ_INSERT_AFTER_N(n, d, i, a) \
161 CT_ASSERT((i)->next##n == 0); \
162 CT_ASSERT((i)->prev##n == 0); \
165 (a)->next##n->prev##n = (i); \
168 (i)->next##n = (a)->next##n; \
169 (i)->prev##n = (a); \
170 (a)->next##n = (i); \
173 #define DEQ_INSERT_AFTER(d, i, a) DEQ_INSERT_AFTER_N(, d, i, a)
175 #define DEQ_REMOVE_N(n, d, i) \
178 (i)->next##n->prev##n = (i)->prev##n; \
180 (d).tail = (i)->prev##n; \
182 (i)->prev##n->next##n = (i)->next##n; \
184 (d).head = (i)->next##n; \
185 CT_ASSERT((d).size > 0); \
189 CT_ASSERT((d).size || (!(d).head && !(d).tail)); \
191 #define DEQ_REMOVE(d, i) DEQ_REMOVE_N(, d, i)
193 #define DEQ_APPEND_N(n, d1, d2) \
197 else if ((d2).head) { \
198 (d1).tail->next##n = (d2).head; \
199 (d2).head->prev##n = (d1).tail; \
200 (d1).tail = (d2).tail; \
201 (d1).size += (d2).size; \
205 #define DEQ_APPEND(d1, d2) DEQ_APPEND_N(, d1, d2)