#define AQUEUE_HEAD(name, type) \ struct name { \ struct type *aqh_next; \ struct type *aqh_prev; \ struct type *aqh_tailprev; \ } #define AQUEUE_HEAD_INITIALIZER(head) { \ (__typeof (head.aqh_next))&(head.aqh_prev), \ NULL, \ (__typeof (head.aqh_tailprev))&(head.aqh_prev) \ } #define AQUEUE_ENTRY(type) \ struct { \ struct type *aqe_next; \ struct type *aqe_prev; \ } #define AQUEUE_EMPTY(head) ((head)->aqh_next == &(head)->aqh_prev) #define AQUEUE_FIRST(head) ((head)->aqh_next) #define AQUEUE_FOREACH(var, head, field) \ for ((var) = AQUEUE_FIRST((head)); \ AQUEUE_NEXT((var), field) != NULL; \ (var) = AQUEUE_NEXT((var), field)) #define AQUEUE_FOREACH_REVERSE(var, head, field) \ for ((var) = AQUEUE_LAST((head)); \ (var); \ AQUEUE_PREV((var), field) != NULL; \ (var) = AQUEUE_PREV((var), field)) #define AQUEUE_INIT(head) do { \ (head)->aqh_next = \ (__typeof ((*(head)).aqh_next))(&((head)->aqh_prev)); \ (head)->aqh_prev = NULL; \ (head)->aqh_tailprev = \ (__typeof ((*(head)).aqh_tailprev))(&((head)->aqh_prev)); \ } while (0) /* insert elm2 after eml1 */ #define AQUEUE_INSERT_AFTER(elm1, elm2, field) do { \ AQUEUE_PREV((elm2), field) = (elm1); \ AQUEUE_NEXT((elm2), field) = AQUEUE_NEXT((elm1), field); \ AQUEUE_NEXT((elm1), field) = (elm2); \ AQUEUE_PREV(AQUEUE_NEXT((elm1), field) = (elm2); \ } while (0) /* insert elm2 before eml1 */ #define AQUEUE_INSERT_BEFORE(elm1, elm2, field) do { \ AQUEUE_NEXT((elm2), field) = (elm1); \ AQUEUE_PREV((elm2), field) = AQUEUE_NEXT((elm1), field); \ AQUEUE_PREV((elm1), field) = (elm2); \ AQUEUE_NEXT(AQUEUE_PREV((elm1), field) = (elm2); \ } while (0) #define AQUEUE_INSERT_HEAD(head, elm, field) do { \ AQUEUE_PREV((elm), field) = (head); \ AQUEUE_NEXT((elm), field) = (head)->aqh_next; \ AQUEUE_PREV((head)->aqh_next, field) = (elm); \ (head)->aqh_next = (elm); \ } while (0) /* AQUEUE_NEXT((elm), field) = (__typeof (elm))&(head)->aqh_prev; */ #define AQUEUE_INSERT_TAIL(head, elm, field) do { \ AQUEUE_NEXT((elm), field) = (head)->aqh_tailprev; \ AQUEUE_PREV((elm), field) = AQUEUE_PREV((head)->aqh_tailprev, field); \ AQUEUE_NEXT((head)->aqh_tailprev, field) = (elm); \ (head)->aqh_tailprev = (elm); \ } while (0) #define AQUEUE_LAST(head) ((head)->aqh_tailprev) #define AQUEUE_NEXT(elm, field) ((elm)->field.aqe_next) #define AQUEUE_PREV(elm, field) ((elm)->field.aqe_prev) #define AQUEUE_REMOVE(elm, field) do { \ AQUEUE_NEXT(AQUEUE_PREV((elm), field), field) = \ AQUEUE_NEXT((elm), field); \ AQUEUE_PREV(AQUEUE_NEXT((elm), field), field) = \ AQUEUE_PREV((elm), field); \ } while (0) #define AQUEUE_ISLAST(elm, field) \ (AQUEUE_NEXT(AQUEUE_NEXT((elm), field), field) == NULL) #define AQUEUE_ISFIRST(elm, field) \ (AQUEUE_PREV(AQUEUE_PREV((elm), field), field) == NULL) #define AQUEUE_VALID(elm, field) \ (AQUEUE_PREV((elm), field) != NULL && AQUEUE_NEXT((elm), field) != NULL)