1 #ifndef _CORE_LIST_H_
2 #define _CORE_LIST_H_
3
4 #if defined(__cplusplus)
5 extern "C" {
6 #endif
7
8 #if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) || defined(__GNUC__)) && \
9 !defined(inline) && !defined(__cplusplus)
10 #define inline __inline
11 #endif
12
13 struct core_list_head {
14 struct core_list_head *prev;
15 struct core_list_head *next;
16 };
17
18 /*
19 * Get offset of a member variable.
20 *
21 * @param[in] type the type of the struct this is embedded in.
22 * @param[in] member the name of the variable within the struct.
23 */
24 #ifdef offsetof
25 #undef offsetof
26 #endif
27 #define offsetof(type, member) ((size_t)&(((type *)0)->member))
28
29 /*
30 * Get the struct for this entry.
31 *
32 * @param[in] ptr the list head to take the element from.
33 * @param[in] type the type of the struct this is embedded in.
34 * @param[in] member the name of the variable within the struct.
35 */
36 #define container_of(ptr, type, member) \
37 ((type *) ((char *) (ptr) - offsetof(type, member)))
38
CORE_INIT_LIST_HEAD(struct core_list_head * list)39 static inline void CORE_INIT_LIST_HEAD(struct core_list_head *list)
40 {
41 list->next = list;
42 list->prev = list;
43 }
44
45 /*
46 * Insert a new entry between two known consecutive entries.
47 *
48 * This is only for internal list manipulation where we know
49 * the prev/next entries already!
50 */
__core_list_add(struct core_list_head * node,struct core_list_head * prev,struct core_list_head * next)51 static inline void __core_list_add(struct core_list_head *node,
52 struct core_list_head *prev,
53 struct core_list_head *next)
54 {
55 next->prev = node;
56 node->next = next;
57 node->prev = prev;
58 prev->next = node;
59 }
60
61 /**
62 * core_list_add - add a new entry
63 * @node: new entry to be added
64 * @head: list head to add it after
65 *
66 * Insert a new entry after the specified head.
67 * This is good for implementing stacks.
68 */
core_list_add(struct core_list_head * node,struct core_list_head * head)69 static inline void core_list_add(struct core_list_head *node, struct core_list_head *head)
70 {
71 __core_list_add(node, head, head->next);
72 }
73
74 /**
75 * core_list_add_tail - add a new entry
76 * @node: new entry to be added
77 * @head: list head to add it before
78 *
79 * Insert a new entry before the specified head.
80 * This is useful for implementing queues.
81 */
core_list_add_tail(struct core_list_head * node,struct core_list_head * head)82 static inline void core_list_add_tail(struct core_list_head *node, struct core_list_head *head)
83 {
84 __core_list_add(node, head->prev, head);
85 }
86
87 /*
88 * Delete a list entry by making the prev/next entries
89 * point to each other.
90 *
91 * This is only for internal list manipulation where we know
92 * the prev/next entries already!
93 */
__core_list_del(struct core_list_head * prev,struct core_list_head * next)94 static inline void __core_list_del(struct core_list_head *prev, struct core_list_head *next)
95 {
96 next->prev = prev;
97 prev->next = next;
98 }
99
100 /**
101 * core_list_del - deletes entry from list.
102 * @entry: the element to delete from the list.
103 * Note: list_empty() on entry does not return true after this, the entry is
104 * in an undefined state.
105 */
__core_list_del_entry(struct core_list_head * entry)106 static inline void __core_list_del_entry(struct core_list_head *entry)
107 {
108 __core_list_del(entry->prev, entry->next);
109 }
110
core_list_del(struct core_list_head * entry)111 static inline void core_list_del(struct core_list_head *entry)
112 {
113 __core_list_del_entry(entry);
114 entry->next = entry;
115 entry->prev = entry;
116 }
117
118 /**
119 * core_list_empty - tests whether a list is empty
120 * @head: the list to test.
121 */
core_list_empty(const struct core_list_head * head)122 static inline int core_list_empty(const struct core_list_head *head)
123 {
124 return head->next == head;
125 }
126
127 /**
128 * core_list_entry - get the struct for this entry
129 * @ptr: the &struct core_list_head pointer.
130 * @type: the type of the struct this is embedded in.
131 * @member: the name of the core_list_head within the struct.
132 */
133 #define core_list_entry(ptr, type, member) \
134 container_of(ptr, type, member)
135
136 /**
137 * core_list_first_entry - get the first element from a list
138 * @ptr: the list head to take the element from.
139 * @type: the type of the struct this is embedded in.
140 * @member: the name of the core_list_head within the struct.
141 *
142 * Note, that list is expected to be not empty.
143 */
144 #define core_list_first_entry(ptr, type, member) \
145 core_list_entry((ptr)->next, type, member)
146
147 /**
148 * core_list_next_entry - get the next element in list
149 * @pos: the type * to cursor
150 * @member: the name of the core_list_head within the struct.
151 * @type: the type of the struct this is embedded in
152 */
153 #define core_list_next_entry(pos, member, type) \
154 core_list_entry((pos)->member.next, type, member)
155
156 /**
157 * core_list_for_each_entry - iterate over list of given type
158 * @pos: the type * to use as a loop cursor.
159 * @head: the head for your list.
160 * @member: the name of the core_list_head within the struct.
161 * @type: the type of the struct this is embedded in
162 */
163 #define core_list_for_each_entry(pos, head, member, type) \
164 for (pos = core_list_first_entry(head, type, member); \
165 &pos->member != (head); \
166 pos = core_list_next_entry(pos, member, type))
167
168 /**
169 * core_list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
170 * @pos: the type * to use as a loop cursor.
171 * @n: another type * to use as temporary storage
172 * @head: the head for your list.
173 * @member: the name of the core_list_head within the struct.
174 * @type: the type of the struct this is embedded in
175 */
176 #define core_list_for_each_entry_safe(pos, n, head, member, type) \
177 for (pos = core_list_first_entry(head, type, member), \
178 n = core_list_next_entry(pos, member, type); \
179 &pos->member != (head); \
180 pos = n, n = core_list_next_entry(n, member, type))
181
182 #if defined(__cplusplus)
183 }
184 #endif
185
186 #endif
187
188