]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/jemalloc/include/jemalloc/internal/qr.h
MFV r353551: 10452 ZoL: merge in large dnode feature fixes
[FreeBSD/FreeBSD.git] / contrib / jemalloc / include / jemalloc / internal / qr.h
1 #ifndef JEMALLOC_INTERNAL_QR_H
2 #define JEMALLOC_INTERNAL_QR_H
3
4 /* Ring definitions. */
5 #define qr(a_type)                                                      \
6 struct {                                                                \
7         a_type  *qre_next;                                              \
8         a_type  *qre_prev;                                              \
9 }
10
11 /* Ring functions. */
12 #define qr_new(a_qr, a_field) do {                                      \
13         (a_qr)->a_field.qre_next = (a_qr);                              \
14         (a_qr)->a_field.qre_prev = (a_qr);                              \
15 } while (0)
16
17 #define qr_next(a_qr, a_field) ((a_qr)->a_field.qre_next)
18
19 #define qr_prev(a_qr, a_field) ((a_qr)->a_field.qre_prev)
20
21 #define qr_before_insert(a_qrelm, a_qr, a_field) do {                   \
22         (a_qr)->a_field.qre_prev = (a_qrelm)->a_field.qre_prev;         \
23         (a_qr)->a_field.qre_next = (a_qrelm);                           \
24         (a_qr)->a_field.qre_prev->a_field.qre_next = (a_qr);            \
25         (a_qrelm)->a_field.qre_prev = (a_qr);                           \
26 } while (0)
27
28 #define qr_after_insert(a_qrelm, a_qr, a_field) do {                    \
29         (a_qr)->a_field.qre_next = (a_qrelm)->a_field.qre_next;         \
30         (a_qr)->a_field.qre_prev = (a_qrelm);                           \
31         (a_qr)->a_field.qre_next->a_field.qre_prev = (a_qr);            \
32         (a_qrelm)->a_field.qre_next = (a_qr);                           \
33 } while (0)
34
35 #define qr_meld(a_qr_a, a_qr_b, a_type, a_field) do {                   \
36         a_type *t;                                                      \
37         (a_qr_a)->a_field.qre_prev->a_field.qre_next = (a_qr_b);        \
38         (a_qr_b)->a_field.qre_prev->a_field.qre_next = (a_qr_a);        \
39         t = (a_qr_a)->a_field.qre_prev;                                 \
40         (a_qr_a)->a_field.qre_prev = (a_qr_b)->a_field.qre_prev;        \
41         (a_qr_b)->a_field.qre_prev = t;                                 \
42 } while (0)
43
44 /*
45  * qr_meld() and qr_split() are functionally equivalent, so there's no need to
46  * have two copies of the code.
47  */
48 #define qr_split(a_qr_a, a_qr_b, a_type, a_field)                       \
49         qr_meld((a_qr_a), (a_qr_b), a_type, a_field)
50
51 #define qr_remove(a_qr, a_field) do {                                   \
52         (a_qr)->a_field.qre_prev->a_field.qre_next                      \
53             = (a_qr)->a_field.qre_next;                                 \
54         (a_qr)->a_field.qre_next->a_field.qre_prev                      \
55             = (a_qr)->a_field.qre_prev;                                 \
56         (a_qr)->a_field.qre_next = (a_qr);                              \
57         (a_qr)->a_field.qre_prev = (a_qr);                              \
58 } while (0)
59
60 #define qr_foreach(var, a_qr, a_field)                                  \
61         for ((var) = (a_qr);                                            \
62             (var) != NULL;                                              \
63             (var) = (((var)->a_field.qre_next != (a_qr))                \
64             ? (var)->a_field.qre_next : NULL))
65
66 #define qr_reverse_foreach(var, a_qr, a_field)                          \
67         for ((var) = ((a_qr) != NULL) ? qr_prev(a_qr, a_field) : NULL;  \
68             (var) != NULL;                                              \
69             (var) = (((var) != (a_qr))                                  \
70             ? (var)->a_field.qre_prev : NULL))
71
72 #endif /* JEMALLOC_INTERNAL_QR_H */