155682Smarkm#ifndef JEMALLOC_INTERNAL_QR_H
255682Smarkm#define JEMALLOC_INTERNAL_QR_H
355682Smarkm
455682Smarkm/* Ring definitions. */
555682Smarkm#define qr(a_type)							\
655682Smarkmstruct {								\
755682Smarkm	a_type	*qre_next;						\
855682Smarkm	a_type	*qre_prev;						\
955682Smarkm}
1055682Smarkm
1155682Smarkm/* Ring functions. */
1255682Smarkm#define qr_new(a_qr, a_field) do {					\
1355682Smarkm	(a_qr)->a_field.qre_next = (a_qr);				\
1455682Smarkm	(a_qr)->a_field.qre_prev = (a_qr);				\
1555682Smarkm} while (0)
1655682Smarkm
1755682Smarkm#define qr_next(a_qr, a_field) ((a_qr)->a_field.qre_next)
1855682Smarkm
1955682Smarkm#define qr_prev(a_qr, a_field) ((a_qr)->a_field.qre_prev)
2055682Smarkm
2155682Smarkm#define qr_before_insert(a_qrelm, a_qr, a_field) do {			\
2255682Smarkm	(a_qr)->a_field.qre_prev = (a_qrelm)->a_field.qre_prev;		\
2355682Smarkm	(a_qr)->a_field.qre_next = (a_qrelm);				\
2455682Smarkm	(a_qr)->a_field.qre_prev->a_field.qre_next = (a_qr);		\
2555682Smarkm	(a_qrelm)->a_field.qre_prev = (a_qr);				\
2655682Smarkm} while (0)
2755682Smarkm
2855682Smarkm#define qr_after_insert(a_qrelm, a_qr, a_field) do {			\
2955682Smarkm	(a_qr)->a_field.qre_next = (a_qrelm)->a_field.qre_next;		\
3055682Smarkm	(a_qr)->a_field.qre_prev = (a_qrelm);				\
3155682Smarkm	(a_qr)->a_field.qre_next->a_field.qre_prev = (a_qr);		\
3255682Smarkm	(a_qrelm)->a_field.qre_next = (a_qr);				\
3355682Smarkm} while (0)
3455682Smarkm
3555682Smarkm#define qr_meld(a_qr_a, a_qr_b, a_type, a_field) do {			\
3655682Smarkm	a_type *t;							\
3755682Smarkm	(a_qr_a)->a_field.qre_prev->a_field.qre_next = (a_qr_b);	\
3855682Smarkm	(a_qr_b)->a_field.qre_prev->a_field.qre_next = (a_qr_a);	\
3955682Smarkm	t = (a_qr_a)->a_field.qre_prev;					\
4055682Smarkm	(a_qr_a)->a_field.qre_prev = (a_qr_b)->a_field.qre_prev;	\
4155682Smarkm	(a_qr_b)->a_field.qre_prev = t;					\
4255682Smarkm} while (0)
4355682Smarkm
4455682Smarkm/*
4555682Smarkm * qr_meld() and qr_split() are functionally equivalent, so there's no need to
4655682Smarkm * have two copies of the code.
4755682Smarkm */
4855682Smarkm#define qr_split(a_qr_a, a_qr_b, a_type, a_field)			\
4955682Smarkm	qr_meld((a_qr_a), (a_qr_b), a_type, a_field)
5055682Smarkm
5155682Smarkm#define qr_remove(a_qr, a_field) do {					\
5255682Smarkm	(a_qr)->a_field.qre_prev->a_field.qre_next			\
5355682Smarkm	    = (a_qr)->a_field.qre_next;					\
5455682Smarkm	(a_qr)->a_field.qre_next->a_field.qre_prev			\
5555682Smarkm	    = (a_qr)->a_field.qre_prev;					\
5655682Smarkm	(a_qr)->a_field.qre_next = (a_qr);				\
5755682Smarkm	(a_qr)->a_field.qre_prev = (a_qr);				\
5855682Smarkm} while (0)
5955682Smarkm
6055682Smarkm#define qr_foreach(var, a_qr, a_field)					\
6155682Smarkm	for ((var) = (a_qr);						\
6255682Smarkm	    (var) != NULL;						\
6355682Smarkm	    (var) = (((var)->a_field.qre_next != (a_qr))		\
6455682Smarkm	    ? (var)->a_field.qre_next : NULL))
6555682Smarkm
6655682Smarkm#define qr_reverse_foreach(var, a_qr, a_field)				\
6755682Smarkm	for ((var) = ((a_qr) != NULL) ? qr_prev(a_qr, a_field) : NULL;	\
6855682Smarkm	    (var) != NULL;						\
6955682Smarkm	    (var) = (((var) != (a_qr))					\
7055682Smarkm	    ? (var)->a_field.qre_prev : NULL))
7155682Smarkm
7255682Smarkm#endif /* JEMALLOC_INTERNAL_QR_H */
7355682Smarkm