1 /* 2 * Copyright (c) 2018-2021, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 */ 7 #ifndef __LISTS_H__ 8 #define __LISTS_H__ 9 10 /********* Bi-directional list operations ********/ 11 /* Bi-directional list structure */ 12 struct bi_list_node_t { 13 struct bi_list_node_t *bprev; 14 struct bi_list_node_t *bnext; 15 }; 16 17 /* Init an empty node. */ 18 #define BI_LIST_INIT_NODE(node) do { \ 19 (node)->bnext = node; \ 20 (node)->bprev = node; \ 21 } while (0) 22 23 /* Insert a new node after current node: (bnext) of current. */ 24 #define BI_LIST_INSERT_AFTER(curr, node) do { \ 25 (node)->bnext = (curr)->bnext; \ 26 (node)->bprev = curr; \ 27 (curr)->bnext->bprev = node; \ 28 (curr)->bnext = node; \ 29 } while (0) 30 31 /* Add one node into list as the tail: (bprev) of head. */ 32 #define BI_LIST_INSERT_BEFORE(curr, node) do { \ 33 (curr)->bprev->bnext = node; \ 34 (node)->bprev = (curr)->bprev; \ 35 (curr)->bprev = node; \ 36 (node)->bnext = curr; \ 37 } while (0) 38 39 /* Remove one node from the list. */ 40 #define BI_LIST_REMOVE_NODE(node) do { \ 41 (node)->bprev->bnext = (node)->bnext; \ 42 (node)->bnext->bprev = (node)->bprev; \ 43 } while (0) 44 45 /* Is the head empty? */ 46 #define BI_LIST_IS_EMPTY(head) ((head)->bnext == (head)) 47 48 /* The node's next node. */ 49 #define BI_LIST_NEXT_NODE(node) ((node)->bnext) 50 51 /* Go through each node of a list. */ 52 #define BI_LIST_FOR_EACH(node, head) \ 53 for (node = (head)->bnext; node != head; node = (node)->bnext) 54 55 /********* Uni-directional list operations ********/ 56 /* Initialize the head node. */ 57 #define UNI_LISI_INIT_NODE(head, link) do { \ 58 if ((head) != NULL) { \ 59 (head)->link = NULL; \ 60 } \ 61 } while (0) 62 63 /* Insert a new node after given position node. */ 64 #define UNI_LIST_INSERT_AFTER(posi, node, link) do { \ 65 (node)->link = (posi)->link; \ 66 (posi)->link = node; \ 67 } while (0) 68 69 /* Is list empty? */ 70 #define UNI_LIST_IS_EMPTY(node, link) \ 71 ((node == NULL) || ((node)->link == NULL)) 72 73 /* Pick the next node. */ 74 #define UNI_LIST_NEXT_NODE(node, link) ((node)->link) 75 76 /* Remove one node from the list. */ 77 #define UNI_LIST_REMOVE_NODE(prev, node, link) do { \ 78 (prev)->link = (node)->link; \ 79 (node)->link = NULL; \ 80 } while (0) 81 82 /* Remove node by its pointer ('pointer = &prev_of_node->link'). */ 83 #define UNI_LIST_REMOVE_NODE_BY_PNODE(pnode, link) \ 84 *(pnode) = (*(pnode))->link 85 86 /* Move a node after posi node. */ 87 #define UNI_LIST_MOVE_AFTER(posi, prev, node, link) do {\ 88 if (prev != NULL) { \ 89 (prev)->link = (node)->link; \ 90 (node)->link = (posi)->link; \ 91 (posi)->link = node; \ 92 } \ 93 } while (0) 94 95 /* Go through each node of a list. */ 96 #define UNI_LIST_FOREACH(node, head, link) \ 97 for (node = (head)->link; node != NULL; node = (node)->link) 98 99 /* Go through each node of a list with prev node recorded. */ 100 #define UNI_LIST_FOREACH_NODE_PREV(prev, node, head, link) \ 101 for (prev = NULL, node = (head)->link; \ 102 node != NULL; prev = node, node = (prev)->link) 103 104 /* Go through each node of a list with recording node and its holder. */ 105 #define UNI_LIST_FOREACH_NODE_PNODE(pnode, node, head, link) \ 106 for (pnode = &(head)->link, node = (head)->link; \ 107 node != NULL; \ 108 pnode = &(node)->link, node = (node)->link) 109 110 #endif /* __LISTS_H__ */ 111