• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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