1 /* 2 * This file is part of the openHiTLS project. 3 * 4 * openHiTLS is licensed under the Mulan PSL v2. 5 * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 * You may obtain a copy of Mulan PSL v2 at: 7 * 8 * http://license.coscl.org.cn/MulanPSL2 9 * 10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13 * See the Mulan PSL v2 for more details. 14 */ 15 16 #ifndef BSL_MODULE_LIST_H 17 #define BSL_MODULE_LIST_H 18 19 #include <stdint.h> 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 /* 26 * This structure is used to store the forward and backward pointers of nodes in the bidirectional linked list. 27 * This linked list does not contain substantial data areas and is generally used to organize (concatenate) data nodes. 28 */ 29 typedef struct ListHeadSt { 30 struct ListHeadSt *next, *prev; 31 } ListHead; 32 33 /** 34 * @brief initialize the linked list when the linked list is reused 35 * 36 * @param head [IN] The address of the head node of the list 37 */ 38 #define LIST_INIT(head) (head)->next = (head)->prev = (head) 39 40 /** 41 * @brief Insert the 'item' node after the 'where' node. 42 Before the change: where->A->B. After the change: where->item->A->B 43 * 44 * @param where [IN] The address where the item will be inserted after 45 * @param item [IN] Address of the node(item) to be inserted 46 */ 47 #define LIST_ADD_AFTER(where, item) do { \ 48 (item)->next = (where)->next; \ 49 (item)->prev = (where); \ 50 (where)->next = (item); \ 51 (item)->next->prev = (item); \ 52 } while (0) 53 54 /** 55 * @brief Insert the 'item' node before the 'where' node. 56 * Before change: A->where->B. After change: A->item->where->B 57 * 58 * @param where [IN] The address where the item will be inserted before 59 * @param item [IN] Address of the node to be inserted 60 */ 61 #define LIST_ADD_BEFORE(where, item) LIST_ADD_AFTER((where)->prev, (item)) 62 63 /** 64 * @brief Delete the node item. 65 * 66 * @param item [IN] The address of the item to be removed 67 */ 68 #define LIST_REMOVE(item) do { \ 69 (item)->prev->next = (item)->next; \ 70 (item)->next->prev = (item)->prev; \ 71 } while (0) 72 73 /** 74 * @brief Check whether a list is empty 75 * 76 * @param head [IN] The address of the list to be checked. 77 */ 78 #define LIST_IS_EMPTY(head) ((head)->next == (head)) 79 80 /** 81 * @brief Travel through a list safety 82 * 83 * @param head [IN] Linked list to be traversed (The head of a list) 84 * @param temp [IN] Point to the current node to safely delete the current node 85 * @param item [IN] A temporary list node item for travelling the list 86 */ 87 #define LIST_FOR_EACH_ITEM_SAFE(item, temp, head) \ 88 for ((item) = (head)->next, (temp) = (item)->next; (item) != (head); (item) = (temp), (temp) = (item)->next) 89 90 /** 91 * @brief Find the start address of the struct(large node) where the node is located 92 * through a node (small node) in the linked list. 93 * 94 * @param item [IN] The address of a list item 95 * @param type [IN] Type of the large node that contains the linked list node. 96 * @param member [IN] Name of the list node in the structure 97 * 98 * Note: 99 * Each struct variable forms a large node (including data and list nodes). 100 * The large node is connected through the list(small node). 101 * --------- --------- --------- -- ---- 102 * | pre |<---| pre |<---| pre | |==>small node | 103 * | next |--->| next |--->| next | | | 104 * --------- --------- --------- -- | ===> Large node 105 * | data1 | | data1 | | data1 | | 106 * | data2 | | data2 | | data2 | | 107 * --------- --------- --------- ---- 108 * The reason why the list is not directly used as the big node is that 109 * the list (ListHead type) has only the head and tail pointers and does not contain the data area. 110 * In this way, the list can be used for mounting any data and is universal. 111 */ 112 #define LIST_ENTRY(item, type, member) \ 113 ((type *)((uintptr_t)(char *)(item) - (uintptr_t)(&((type *)0)->member))) 114 115 #ifdef __cplusplus 116 } 117 #endif 118 #endif // BSL_MODULE_LIST_H