1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /*
3 * Copyright (c) 2020-2021 Rockchip Electronics Co., Ltd.
4 */
5
6 #ifndef _HAL_LIST_H_
7 #define _HAL_LIST_H_
8
9 /***************************** Structure Definition **************************/
10
11 /** double list struct */
12 struct HAL_LIST_NODE {
13 struct HAL_LIST_NODE *next;
14 struct HAL_LIST_NODE *prev;
15 };
16
17 typedef struct HAL_LIST_NODE HAL_LIST;
18
19 /***************************** Function Declare ******************************/
20 /**
21 * @brief cast a member of a structure out to the containing structure
22 * @param ptr: the pointer to the member.
23 * @param type: the type of the container struct this is embedded in.
24 * @param member: the name of the member within the struct.
25 */
26 #define HAL_CONTAINER_OF(ptr, type, member) \
27 ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
28
29 /**
30 * @brief initialize a list object
31 * @param object: object itself.
32 */
33 #define HAL_LIST_OBJECT_INIT(object) { &(object), &(object) }
34
35 #define HAL_LIST_HEAD_INIT(name) { &(name), &(name) }
36
37 /**
38 * @brief initialize a list head
39 * @param name: list name..
40 */
41 #define HAL_LIST_HEAD(name) \
42 struct HAL_LIST_NODE name = HAL_LIST_HEAD_INIT(name)
43
44 /**
45 * @brief initialize a list
46 * @param l: list to be initialized
47 */
HAL_LIST_Init(HAL_LIST * l)48 __STATIC_INLINE void HAL_LIST_Init(HAL_LIST *l)
49 {
50 l->next = l->prev = l;
51 }
52
53 /**
54 * @brief insert a node after a list
55 * @param l: list to insert it
56 * @param n: new node to be inserted
57 */
HAL_LIST_InsertAfter(HAL_LIST * l,HAL_LIST * n)58 __STATIC_INLINE void HAL_LIST_InsertAfter(HAL_LIST *l, HAL_LIST *n)
59 {
60 l->next->prev = n;
61 n->next = l->next;
62
63 l->next = n;
64 n->prev = l;
65 }
66
67 /**
68 * @brief insert a node before a list
69 * @param n: new node to be inserted
70 * @param l: list to insert it
71 */
HAL_LIST_InsertBefore(HAL_LIST * l,HAL_LIST * n)72 __STATIC_INLINE void HAL_LIST_InsertBefore(HAL_LIST *l, HAL_LIST *n)
73 {
74 l->prev->next = n;
75 n->prev = l->prev;
76
77 l->prev = n;
78 n->next = l;
79 }
80
81 /**
82 * @brief remove node from list.
83 * @param n: the node to remove from the list.
84 */
HAL_LIST_Remove(HAL_LIST * n)85 __STATIC_INLINE void HAL_LIST_Remove(HAL_LIST *n)
86 {
87 n->next->prev = n->prev;
88 n->prev->next = n->next;
89
90 n->next = n->prev = n;
91 }
92
93 /**
94 * @brief tests whether a list is empty
95 * @param l: the list to test.
96 */
HAL_LIST_IsEmpty(const HAL_LIST * l)97 __STATIC_INLINE int HAL_LIST_IsEmpty(const HAL_LIST *l)
98 {
99 return l->next == l;
100 }
101
102 /**
103 * @brief get the list length
104 * @param l: the list to get.
105 */
HAL_LIST_Len(const HAL_LIST * l)106 __STATIC_INLINE uint32_t HAL_LIST_Len(const HAL_LIST *l)
107 {
108 uint32_t len = 0;
109 const HAL_LIST *p = l;
110
111 while (p->next != l) {
112 p = p->next;
113 len++;
114 }
115
116 return len;
117 }
118
119 /**
120 * @brief get the struct for this entry
121 * @param node: the entry point
122 * @param type: the type of structure
123 * @param member: the name of list in structure
124 */
125 #define HAL_LIST_ENTRY(node, type, member) \
126 HAL_CONTAINER_OF(node, type, member)
127
128 /**
129 * @brief iterate over a list
130 * @param pos: the rt_list_t * to use as a loop cursor.
131 * @param head: the head for your list.
132 */
133 #define HAL_LIST_FOR_EACH(pos, head) \
134 for (pos = (head)->next; pos != (head); pos = pos->next)
135
136 /**
137 * @brief iterate over a list safe against removal of list entry
138 * @param pos: the rt_list_t * to use as a loop cursor.
139 * @param n: another rt_list_t * to use as temporary storage
140 * @param head: the head for your list.
141 */
142 #define HAL_LIST_FOR_EACH_SAFE(pos, n, head) \
143 for (pos = (head)->next, n = pos->next; pos != (head); \
144 pos = n, n = pos->next)
145
146 /**
147 * @brief iterate over list of given type
148 * @param pos: the type * to use as a loop cursor.
149 * @param head: the head for your list.
150 * @param member: the name of the list_struct within the struct.
151 */
152 #define HAL_LIST_FOR_EACH_ENTRY(pos, head, member) \
153 for (pos = HAL_LIST_ENTRY((head)->next, __typeof__(*pos), member); \
154 &pos->member != (head); \
155 pos = HAL_LIST_ENTRY(pos->member.next, __typeof__(*pos), member))
156
157 /**
158 * @brief iterate over list of given type safe against removal of list entry
159 * @param pos: the type * to use as a loop cursor.
160 * @param n: another type * to use as temporary storage
161 * @param head: the head for your list.
162 * @param member: the name of the list_struct within the struct.
163 */
164 #define HAL_LIST_FOR_EACH_ENTRY_SAFE(pos, n, head, member) \
165 for (pos = HAL_LIST_ENTRY((head)->next, __typeof__(*pos), member), \
166 n = HAL_LIST_ENTRY(pos->member.next, __typeof__(*pos), member); \
167 &pos->member != (head); \
168 pos = n, n = HAL_LIST_ENTRY(n->member.next, __typeof__(*n), member))
169
170 /**
171 * @brief get the first element from a list
172 * @param ptr: the list head to take the element from.
173 * @param type: the type of the struct this is embedded in.
174 * @param member: the name of the list_struct within the struct.
175 *
176 * Note, that list is expected to be not empty.
177 */
178 #define HAL_LIST_FIRST_ENTRY(ptr, type, member) \
179 HAL_LIST_ENTRY((ptr)->next, type, member)
180
181 #endif
182