3 #ifdef RELATIVE_POINTERS
4 #define PTR(p, f) ((typeof((p)->f))((unsigned long)(p) + (unsigned long)(p)->f))
5 #define PTRSET(p, f, v) ((p)->f = (void *)((unsigned long)(v) - (unsigned long)(p)))
7 #define PTR(p, f) (p)->f
8 #define PTRSET(p, f, v) ((p)->f = (v))
11 static inline int __snap(xqindex size)
15 return 1 << ((sizeof(size) * 8) - __builtin_clz(size) - 1);
18 void xq_free(struct xq *xq) {
19 xq_mfree((void *)PTR(xq, queue));
20 memset(xq, 0, sizeof(struct xq));
23 void xq_init_empty(struct xq *xq, xqindex size, void *mem)
27 PTRSET(xq, queue, mem);
28 xq->size = __snap(size);
29 xq_release(&xq->lock);
32 void xq_init_map(struct xq *xq,
35 xqindex (*mapfn)(xqindex),
38 xqindex t, *qmem = mem;
41 PTRSET(xq, queue, qmem);
42 xq->size = __snap(size);
43 for (t = 0; t < count; t++)
45 xq_release(&xq->lock);
48 void xq_init_seq(struct xq *xq, xqindex size, xqindex count, void *mem)
50 xqindex t, *qmem = mem;
53 PTRSET(xq, queue, qmem);
54 xq->size = __snap(size);
55 for (t = 0; t < count; t++)
57 xq_release(&xq->lock);
60 xqindex *xq_alloc_empty(struct xq *xq, xqindex size)
62 xqindex *mem = xq_malloc(size * sizeof(xqindex));
65 xq_init_empty(xq, size, mem);
69 xqindex *xq_alloc_map(struct xq *xq,
72 xqindex (*mapfn)(xqindex) )
74 xqindex *mem = xq_malloc(size * sizeof(xqindex));
77 xq_init_map(xq, size, count, mapfn, mem);
81 xqindex *xq_alloc_seq(struct xq *xq, xqindex size, xqindex count)
83 xqindex *mem = xq_malloc(size * sizeof(xqindex));
86 xq_init_seq(xq, size, count, mem);
90 xqindex xq_size(struct xq *xq)
95 xqindex xq_count(struct xq *xq)
97 return xq->head - xq->tail - 1;
100 xqindex xq_element(struct xq *xq, xqindex index)
102 return PTR(xq, queue)[index & (xq->size - 1)];
105 void xq_print(struct xq *xq)
109 LOGMSG("xq head: %lu, tail: %lu, size: %lu\n",
110 (unsigned long)xq->head,
111 (unsigned long)xq->tail,
112 (unsigned long)xq->size);
120 (unsigned long)xq_element(xq, i) );
125 xqindex __xq_append_head(struct xq *xq, xqindex nr)
127 xqindex head = xq->head;
128 xq->head = head + nr;
132 xqindex xq_append_heads(struct xq *xq,
136 xqindex i, mask, head;
137 xqindex serial = xq_acquire(&xq->lock, nr);
139 if (!(xq_count(xq) + nr <= xq->size)) {
145 head = __xq_append_head(xq, nr);
146 for (i = 0; i < nr; i++)
147 PTR(xq, queue)[(head + i) & mask] = heads[i];
149 xq_release(&xq->lock);
153 xqindex xq_append_head(struct xq *xq, xqindex xqi)
155 xqindex serial = xq_acquire(&xq->lock, 1);
157 if (xq_count(xq) >= xq->size) {
161 PTR(xq, queue)[__xq_append_head(xq, 1) & (xq->size -1)] = xqi;
163 xq_release(&xq->lock);
167 xqindex __xq_pop_head(struct xq *xq, xqindex nr)
169 xqindex head = xq->head;
170 xq->head = head - nr;
174 xqindex xq_pop_heads(struct xq *xq,
178 xqindex i, mask, head;
179 xqindex serial = xq_acquire(&xq->lock, nr);
181 if (xq_count(xq) < nr) {
187 head = __xq_pop_head(xq, nr);
188 for (i = 0; i < nr; i++)
189 heads[i] = PTR(xq, queue)[(head - i) & mask];
191 xq_release(&xq->lock);
195 xqindex xq_pop_head(struct xq *xq)
197 xqindex value = None;
198 (void)xq_acquire(&xq->lock, 1);
201 value = PTR(xq, queue)[__xq_pop_head(xq, 1) & (xq->size -1)];
203 xq_release(&xq->lock);
207 xqindex __xq_append_tail(struct xq *xq, xqindex nr)
209 xqindex tail = xq->tail;
210 xq->tail = tail - nr;
214 xqindex xq_append_tails(struct xq *xq,
218 xqindex i, mask, tail;
219 xqindex serial = xq_acquire(&xq->lock, nr);
221 if (!(xq_count(xq) + nr <= xq->size)) {
227 tail = __xq_append_tail(xq, nr);
228 for (i = 0; i < nr; i++)
229 PTR(xq, queue)[(tail - i) & mask] = tails[i];
231 xq_release(&xq->lock);
235 xqindex xq_append_tail(struct xq *xq, xqindex xqi)
237 xqindex serial = xq_acquire(&xq->lock, 1);
239 if (!(xq_count(xq) + 1 <= xq->size)) {
243 PTR(xq, queue)[__xq_append_tail(xq, 1) & (xq->size -1)] = xqi;
245 xq_release(&xq->lock);
249 xqindex __xq_pop_tail(struct xq *xq, xqindex nr)
251 xqindex tail = xq->tail;
252 xq->tail = tail + nr;
256 xqindex xq_pop_tails(struct xq *xq, xqindex nr, xqindex *tails)
258 xqindex i, mask, tail;
259 xqindex serial = xq_acquire(&xq->lock, nr);
261 if (xq_count(xq) < nr) {
267 tail = __xq_pop_tail(xq, nr);
268 for (i = 0; i < nr; i++)
269 tails[i] = PTR(xq, queue)[(tail + i) & mask];
271 xq_release(&xq->lock);
275 xqindex xq_pop_tail(struct xq *xq)
277 xqindex value = None;
278 (void)xq_acquire(&xq->lock, 1);
281 value = PTR(xq, queue)[__xq_pop_tail(xq, 1) & (xq->size -1)];
283 xq_release(&xq->lock);
287 int xq_head_to_tail(struct xq *headq, struct xq *tailq, xqindex nr)
289 xqindex head, tail, hmask, tmask, *hq, *tq, i, ret = -1;
291 if (headq >= tailq) {
292 xq_acquire(&headq->lock, nr);
293 xq_acquire(&tailq->lock, nr);
295 xq_acquire(&tailq->lock, nr);
296 xq_acquire(&headq->lock, nr);
299 if (xq_count(headq) < nr || xq_count(tailq) + nr > tailq->size)
302 hmask = headq->size -1;
303 tmask = tailq->size -1;
304 head = __xq_pop_head(headq, nr);
305 tail = __xq_append_tail(tailq, nr);
306 hq = PTR(headq, queue);
307 tq = PTR(tailq, queue);
309 for (i = 0; i < nr; i++)
310 tq[(tail - i) & tmask] = hq[(head - i) & hmask];
314 xq_release(&headq->lock);
315 xq_release(&tailq->lock);
323 #include <linux/module.h>
324 #include <xq/xq_exports.h>