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