2 #include <xtypes/domain.h>
4 static inline int __snap(xqindex size)
8 return 1 << ((sizeof(size) * 8) - __builtin_clz(size) - 1);
11 void xq_free(struct xq *xq) {
12 xtypes_free((void *)XPTR(&xq->queue));
13 memset(xq, 0, sizeof(struct xq));
16 void xq_init_empty(struct xq *xq, xqindex size, void *mem)
20 XPTRSET(&xq->queue, mem);
21 xq->size = __snap(size);
22 xlock_release(&xq->lock);
25 void xq_init_map(struct xq *xq,
28 xqindex (*mapfn)(xqindex),
31 xqindex t, *qmem = mem;
34 XPTRSET(&xq->queue, qmem);
35 xq->size = __snap(size);
36 for (t = 0; t < count; t++)
38 xlock_release(&xq->lock);
41 void xq_init_seq(struct xq *xq, xqindex size, xqindex count, void *mem)
43 xqindex t, *qmem = mem;
46 XPTRSET(&xq->queue, qmem);
47 xq->size = __snap(size);
48 for (t = 0; t < count; t++)
50 xlock_release(&xq->lock);
53 xqindex *xq_alloc_empty(struct xq *xq, xqindex size)
55 xqindex *mem = xtypes_malloc(size * sizeof(xqindex));
58 xq_init_empty(xq, size, mem);
62 xqindex *xq_alloc_map(struct xq *xq,
65 xqindex (*mapfn)(xqindex) )
67 xqindex *mem = xtypes_malloc(size * sizeof(xqindex));
70 xq_init_map(xq, size, count, mapfn, mem);
74 xqindex *xq_alloc_seq(struct xq *xq, xqindex size, xqindex count)
76 xqindex *mem = xtypes_malloc(size * sizeof(xqindex));
79 xq_init_seq(xq, size, count, mem);
83 xqindex xq_size(struct xq *xq)
88 xqindex xq_count(struct xq *xq)
90 return xq->head - xq->tail - 1;
93 xqindex xq_element(struct xq *xq, xqindex index)
95 return XPTR(&xq->queue)[index & (xq->size - 1)];
98 void xq_print(struct xq *xq)
102 XSEGLOG("xq head: %lu, tail: %lu, size: %lu\n",
103 (unsigned long)xq->head,
104 (unsigned long)xq->tail,
105 (unsigned long)xq->size);
111 XSEGLOG( "%lu %lu\n",
113 (unsigned long)xq_element(xq, i) );
118 xqindex __xq_append_head_idx(struct xq *xq, xqindex nr)
120 xqindex head = xq->head;
121 xq->head = head + nr;
126 xqindex xq_append_heads(struct xq *xq,
130 xqindex i, mask, head;
131 xqindex serial = xlock_acquire(&xq->lock, nr);
133 if (!(xq_count(xq) + nr <= xq->size)) {
139 head = __xq_append_head_idx(xq, nr);
140 for (i = 0; i < nr; i++)
141 XPTR(&xq->queue)[(head + i) & mask] = heads[i];
143 xlock_release(&xq->lock);
148 xqindex __xq_append_head(struct xq *xq, xqindex xqi)
150 if (xq_count(xq) >= xq->size) {
153 XPTR(&xq->queue)[__xq_append_head_idx(xq, 1) & (xq->size -1)] = xqi;
157 xqindex xq_append_head(struct xq *xq, xqindex xqi, unsigned long who)
160 xlock_acquire(&xq->lock, who);
161 serial = __xq_append_head(xq, xqi);
162 xlock_release(&xq->lock);
166 xqindex __xq_pop_head_idx(struct xq *xq, xqindex nr)
168 xqindex head = xq->head - nr;
174 xqindex xq_pop_heads(struct xq *xq,
178 xqindex i, mask, head;
179 xqindex serial = xlock_acquire(&xq->lock, nr);
181 if (xq_count(xq) < nr) {
187 head = __xq_pop_head_idx(xq, nr);
188 for (i = 0; i < nr; i++)
189 heads[i] = XPTR(&xq->queue)[(head - i) & mask];
191 xlock_release(&xq->lock);
196 xqindex __xq_pop_head(struct xq *xq)
198 xqindex value = Noneidx;
201 return XPTR(&xq->queue)[__xq_pop_head_idx(xq, 1) & (xq->size -1)];
204 xqindex xq_pop_head(struct xq *xq, unsigned long who)
206 xqindex value = Noneidx;
207 (void)xlock_acquire(&xq->lock, who);
208 value = __xq_pop_head(xq);
209 xlock_release(&xq->lock);
213 xqindex __xq_peek_head_idx(struct xq *xq, xqindex nr)
215 xqindex head = xq->head - nr;
219 xqindex __xq_peek_head(struct xq *xq)
223 return XPTR(&xq->queue)[__xq_peek_head_idx(xq, 1) & (xq->size -1)];
226 xqindex xq_peek_head(struct xq *xq, unsigned long who)
229 (void)xlock_acquire(&xq->lock, who);
230 value = __xq_peek_head(xq);
231 xlock_release(&xq->lock);
235 xqindex __xq_peek_tail_idx(struct xq *xq, xqindex nr)
237 xqindex tail = xq->tail + nr;
241 xqindex __xq_peek_tail(struct xq *xq)
245 return XPTR(&xq->queue)[__xq_peek_tail_idx(xq, 1) & (xq->size -1)];
248 xqindex xq_peek_tail(struct xq *xq, unsigned long who)
251 (void)xlock_acquire(&xq->lock, who);
252 value = __xq_peek_tail(xq);
253 xlock_release(&xq->lock);
257 xqindex __xq_append_tail_idx(struct xq *xq, xqindex nr)
259 xqindex tail = xq->tail - nr;
265 xqindex xq_append_tails(struct xq *xq,
269 xqindex i, mask, tail;
270 xqindex serial = xlock_acquire(&xq->lock, nr);
272 if (!(xq_count(xq) + nr <= xq->size)) {
278 tail = __xq_append_tail_idx(xq, nr) + nr -1;
279 for (i = 0; i < nr; i++)
280 XPTR(&xq->queue)[(tail - i) & mask] = tails[i];
282 xlock_release(&xq->lock);
287 xqindex __xq_append_tail(struct xq *xq, xqindex xqi)
289 if (!(xq_count(xq) + 1 <= xq->size)) {
292 XPTR(&xq->queue)[__xq_append_tail_idx(xq, 1) & (xq->size -1)] = xqi;
296 xqindex xq_append_tail(struct xq *xq, xqindex xqi, unsigned long who)
298 xqindex serial = Noneidx;
299 xlock_acquire(&xq->lock, who);
300 serial =__xq_append_tail(xq, xqi);
301 xlock_release(&xq->lock);
305 xqindex __xq_pop_tail_idx(struct xq *xq, xqindex nr)
307 xqindex tail = xq->tail;
308 xq->tail = tail + nr;
313 xqindex xq_pop_tails(struct xq *xq, xqindex nr, xqindex *tails)
315 xqindex i, mask, tail;
316 xqindex serial = xlock_acquire(&xq->lock, nr);
318 if (xq_count(xq) < nr) {
324 tail = __xq_pop_tail_idx(xq, nr);
325 for (i = 0; i < nr; i++)
326 tails[i] = XPTR(&xq->queue)[(tail + i) & mask];
328 xlock_release(&xq->lock);
333 xqindex __xq_pop_tail(struct xq *xq)
337 return XPTR(&xq->queue)[__xq_pop_tail_idx(xq, 1) & (xq->size -1)];
340 xqindex xq_pop_tail(struct xq *xq, unsigned long who)
343 (void)xlock_acquire(&xq->lock, who);
344 value = __xq_pop_tail(xq);
345 xlock_release(&xq->lock);
349 int xq_head_to_tail(struct xq *headq, struct xq *tailq, xqindex nr, unsigned long who)
351 xqindex head, tail, hmask, tmask, *hq, *tq, i, ret = -1;
353 if (headq >= tailq) {
354 xlock_acquire(&headq->lock, who);
355 xlock_acquire(&tailq->lock, who);
357 xlock_acquire(&tailq->lock, who);
358 xlock_acquire(&headq->lock, who);
361 if (xq_count(headq) < nr || xq_count(tailq) + nr > tailq->size)
364 hmask = headq->size -1;
365 tmask = tailq->size -1;
366 head = __xq_pop_head_idx(headq, nr);
367 tail = __xq_append_tail_idx(tailq, nr);
368 hq = XPTR(&headq->queue);
369 tq = XPTR(&tailq->queue);
371 for (i = 0; i < nr; i++)
372 tq[(tail + i) & tmask] = hq[(head + i) & hmask];
376 xlock_release(&headq->lock);
377 xlock_release(&tailq->lock);
381 int __xq_check(struct xq *xq, xqindex idx)
384 for (i = xq->tail + 1; i != xq->head ; i++) {
385 val = XPTR(&xq->queue)[i & (xq->size -1)];
392 int xq_check(struct xq *xq, xqindex idx, unsigned long who)
395 xlock_acquire(&xq->lock, who);
396 r = __xq_check(xq, idx);
397 xlock_release(&xq->lock);
401 xqindex __xq_resize(struct xq *xq, struct xq *newxq)
403 xqindex i, mask, mask_new, head, tail, val;
404 xqindex nr = xq_count(xq);
406 if (nr > newxq->size) {
411 mask_new = newxq->size -1;
412 head = __xq_peek_head_idx(xq, nr);
413 tail = __xq_append_tail_idx(newxq, nr) + nr -1;
414 for (i = 0; i < nr; i++) {
415 val = XPTR(&xq->queue)[(head + i) & mask];
416 XPTR(&newxq->queue)[(tail - i) & mask_new] = val;
422 xqindex xq_resize(struct xq *xq, struct xq *newxq, unsigned long who)
425 xlock_acquire(&xq->lock, who);
426 xlock_acquire(&newxq->lock, who);
427 r = __xq_resize(xq, newxq);
428 xlock_release(&newxq->lock);
429 xlock_release(&xq->lock);
434 #include <linux/module.h>
435 #include <xtypes/xq_exports.h>