OpenOCD
list.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 
3 /*
4  * Copyright (c) 2010 Isilon Systems, Inc.
5  * Copyright (c) 2010 iX Systems, Inc.
6  * Copyright (c) 2010 Panasas, Inc.
7  * Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
8  * Copyright (c) 2021-2024 by Antonio Borneo <borneo.antonio@gmail.com>
9  * All rights reserved.
10  */
11 
12 /*
13  * Circular doubly linked list implementation.
14  *
15  * The content of this file is mainly copied/inspired from FreeBSD code in:
16  * https://cgit.freebsd.org/src/tree/
17  * files:
18  * sys/compat/linuxkpi/common/include/linux/list.h
19  * sys/compat/linuxkpi/common/include/linux/types.h
20  *
21  * Last aligned with release/13.3.0:
22  *
23  * - Skip 'hlist_*' double linked lists with a single pointer list head.
24  * - Expand WRITE_ONCE().
25  * - Use TAB for indentation.
26  * - Put macro arguments within parenthesis.
27  * - Remove blank lines after an open brace '{'.
28  * - Remove multiple assignment.
29  *
30  * There is an example of using this file in contrib/list_example.c.
31  */
32 
33 #ifndef OPENOCD_HELPER_LIST_H
34 #define OPENOCD_HELPER_LIST_H
35 
36 /* begin OpenOCD changes */
37 
38 #include <assert.h>
39 #include <stddef.h>
40 
41 struct list_head {
42  struct list_head *next;
43  struct list_head *prev;
44 };
45 
46 /* end OpenOCD changes */
47 
48 #define LIST_HEAD_INIT(name) { &(name), &(name) }
49 
50 #define OOCD_LIST_HEAD(name) \
51  struct list_head name = LIST_HEAD_INIT(name)
52 
53 static inline void
55 {
56  list->next = list;
57  list->prev = list;
58 }
59 
60 static inline int
61 list_empty(const struct list_head *head)
62 {
63  return (head->next == head);
64 }
65 
66 static inline int
67 list_empty_careful(const struct list_head *head)
68 {
69  struct list_head *next = head->next;
70 
71  return ((next == head) && (next == head->prev));
72 }
73 
74 static inline void
76 {
77  next->prev = prev;
78  prev->next = next;
79 }
80 
81 static inline void
83 {
84  __list_del(entry->prev, entry->next);
85 }
86 
87 static inline void
88 list_del(struct list_head *entry)
89 {
90  __list_del(entry->prev, entry->next);
91 }
92 
93 static inline void
94 list_replace(struct list_head *old, struct list_head *new)
95 {
96  new->next = old->next;
97  new->next->prev = new;
98  new->prev = old->prev;
99  new->prev->next = new;
100 }
101 
102 static inline void
103 list_replace_init(struct list_head *old, struct list_head *new)
104 {
105  list_replace(old, new);
106  INIT_LIST_HEAD(old);
107 }
108 
109 static inline void
110 linux_list_add(struct list_head *new, struct list_head *prev,
111  struct list_head *next)
112 {
113  assert(next);
114  assert(prev);
115 
116  next->prev = new;
117  new->next = next;
118  new->prev = prev;
119  prev->next = new;
120 }
121 
122 static inline void
123 list_del_init(struct list_head *entry)
124 {
125  list_del(entry);
126  INIT_LIST_HEAD(entry);
127 }
128 
129 #define list_entry(ptr, type, field) container_of(ptr, type, field)
130 
131 #define list_first_entry(ptr, type, member) \
132  list_entry((ptr)->next, type, member)
133 
134 #define list_last_entry(ptr, type, member) \
135  list_entry((ptr)->prev, type, member)
136 
137 #define list_first_entry_or_null(ptr, type, member) \
138  (!list_empty(ptr) ? list_first_entry(ptr, type, member) : NULL)
139 
140 #define list_next_entry(ptr, member) \
141  list_entry(((ptr)->member.next), typeof(*(ptr)), member)
142 
143 #define list_safe_reset_next(ptr, n, member) \
144  (n) = list_next_entry(ptr, member)
145 
146 #define list_prev_entry(ptr, member) \
147  list_entry(((ptr)->member.prev), typeof(*(ptr)), member)
148 
149 #define list_for_each(p, head) \
150  for (p = (head)->next; p != (head); p = (p)->next)
151 
152 #define list_for_each_safe(p, n, head) \
153  for (p = (head)->next, n = (p)->next; p != (head); p = n, n = (p)->next)
154 
155 #define list_for_each_entry(p, h, field) \
156  for (p = list_entry((h)->next, typeof(*p), field); &(p)->field != (h); \
157  p = list_entry((p)->field.next, typeof(*p), field))
158 
159 #define list_for_each_entry_safe(p, n, h, field) \
160  for (p = list_entry((h)->next, typeof(*p), field), \
161  n = list_entry((p)->field.next, typeof(*p), field); &(p)->field != (h);\
162  p = n, n = list_entry(n->field.next, typeof(*n), field))
163 
164 #define list_for_each_entry_from(p, h, field) \
165  for ( ; &(p)->field != (h); \
166  p = list_entry((p)->field.next, typeof(*p), field))
167 
168 #define list_for_each_entry_continue(p, h, field) \
169  for (p = list_next_entry((p), field); &(p)->field != (h); \
170  p = list_next_entry((p), field))
171 
172 #define list_for_each_entry_safe_from(pos, n, head, member) \
173  for (n = list_entry((pos)->member.next, typeof(*pos), member); \
174  &(pos)->member != (head); \
175  pos = n, n = list_entry(n->member.next, typeof(*n), member))
176 
177 #define list_for_each_entry_reverse(p, h, field) \
178  for (p = list_entry((h)->prev, typeof(*p), field); &(p)->field != (h); \
179  p = list_entry((p)->field.prev, typeof(*p), field))
180 
181 #define list_for_each_entry_safe_reverse(p, n, h, field) \
182  for (p = list_entry((h)->prev, typeof(*p), field), \
183  n = list_entry((p)->field.prev, typeof(*p), field); &(p)->field != (h); \
184  p = n, n = list_entry(n->field.prev, typeof(*n), field))
185 
186 #define list_for_each_entry_continue_reverse(p, h, field) \
187  for (p = list_entry((p)->field.prev, typeof(*p), field); &(p)->field != (h); \
188  p = list_entry((p)->field.prev, typeof(*p), field))
189 
190 #define list_for_each_prev(p, h) for (p = (h)->prev; p != (h); p = (p)->prev)
191 
192 #define list_for_each_entry_from_reverse(p, h, field) \
193  for (; &p->field != (h); \
194  p = list_prev_entry(p, field))
195 
196 static inline void
197 list_add(struct list_head *new, struct list_head *head)
198 {
199  linux_list_add(new, head, head->next);
200 }
201 
202 static inline void
203 list_add_tail(struct list_head *new, struct list_head *head)
204 {
205  linux_list_add(new, head->prev, head);
206 }
207 
208 static inline void
209 list_move(struct list_head *list, struct list_head *head)
210 {
211  list_del(list);
212  list_add(list, head);
213 }
214 
215 static inline void
216 list_move_tail(struct list_head *entry, struct list_head *head)
217 {
218  list_del(entry);
219  list_add_tail(entry, head);
220 }
221 
222 static inline void
223 list_rotate_to_front(struct list_head *entry, struct list_head *head)
224 {
225  list_move_tail(entry, head);
226 }
227 
228 static inline void
229 list_bulk_move_tail(struct list_head *head, struct list_head *first,
230  struct list_head *last)
231 {
232  first->prev->next = last->next;
233  last->next->prev = first->prev;
234  head->prev->next = first;
235  first->prev = head->prev;
236  last->next = head;
237  head->prev = last;
238 }
239 
240 static inline void
241 linux_list_splice(const struct list_head *list, struct list_head *prev,
242  struct list_head *next)
243 {
244  struct list_head *first;
245  struct list_head *last;
246 
247  if (list_empty(list))
248  return;
249  first = list->next;
250  last = list->prev;
251  first->prev = prev;
252  prev->next = first;
253  last->next = next;
254  next->prev = last;
255 }
256 
257 static inline void
258 list_splice(const struct list_head *list, struct list_head *head)
259 {
260  linux_list_splice(list, head, head->next);
261 }
262 
263 static inline void
264 list_splice_tail(struct list_head *list, struct list_head *head)
265 {
266  linux_list_splice(list, head->prev, head);
267 }
268 
269 static inline void
270 list_splice_init(struct list_head *list, struct list_head *head)
271 {
272  linux_list_splice(list, head, head->next);
273  INIT_LIST_HEAD(list);
274 }
275 
276 static inline void
277 list_splice_tail_init(struct list_head *list, struct list_head *head)
278 {
279  linux_list_splice(list, head->prev, head);
280  INIT_LIST_HEAD(list);
281 }
282 
283 /*
284  * Double linked lists with a single pointer list head.
285  * IGNORED
286  */
287 
288 static inline int list_is_singular(const struct list_head *head)
289 {
290  return !list_empty(head) && (head->next == head->prev);
291 }
292 
293 static inline void __list_cut_position(struct list_head *list,
294  struct list_head *head, struct list_head *entry)
295 {
296  struct list_head *new_first = entry->next;
297  list->next = head->next;
298  list->next->prev = list;
299  list->prev = entry;
300  entry->next = list;
301  head->next = new_first;
302  new_first->prev = head;
303 }
304 
305 static inline void list_cut_position(struct list_head *list,
306  struct list_head *head, struct list_head *entry)
307 {
308  if (list_empty(head))
309  return;
310  if (list_is_singular(head) &&
311  (head->next != entry && head != entry))
312  return;
313  if (entry == head)
314  INIT_LIST_HEAD(list);
315  else
316  __list_cut_position(list, head, entry);
317 }
318 
319 static inline int list_is_first(const struct list_head *list,
320  const struct list_head *head)
321 {
322  return (list->prev == head);
323 }
324 
325 static inline int list_is_last(const struct list_head *list,
326  const struct list_head *head)
327 {
328  return list->next == head;
329 }
330 
331 static inline size_t
332 list_count_nodes(const struct list_head *list)
333 {
334  const struct list_head *lh;
335  size_t count;
336 
337  count = 0;
338  list_for_each(lh, list) {
339  count++;
340  }
341 
342  return (count);
343 }
344 
345 /*
346  * Double linked lists with a single pointer list head.
347  * IGNORED
348  */
349 
350 /* begin OpenOCD extensions */
351 
359 #define list_for_each_entry_direction(is_fwd, p, h, field) \
360  for (p = list_entry(is_fwd ? (h)->next : (h)->prev, typeof(*p), field); \
361  &(p)->field != (h); \
362  p = list_entry(is_fwd ? (p)->field.next : (p)->field.prev, typeof(*p), field))
363 
368 static inline void list_rotate_left(struct list_head *h)
369 {
370  struct list_head *first;
371 
372  if (!list_empty(h)) {
373  first = h->next;
374  list_move_tail(first, h);
375  }
376 }
377 
378 /* end OpenOCD extensions */
379 
380 #endif /* OPENOCD_HELPER_LIST_H */
static void list_add(struct list_head *new, struct list_head *head)
Definition: list.h:197
static void list_splice(const struct list_head *list, struct list_head *head)
Definition: list.h:258
static void list_bulk_move_tail(struct list_head *head, struct list_head *first, struct list_head *last)
Definition: list.h:229
static void __list_cut_position(struct list_head *list, struct list_head *head, struct list_head *entry)
Definition: list.h:293
static void list_splice_tail_init(struct list_head *list, struct list_head *head)
Definition: list.h:277
static void list_move_tail(struct list_head *entry, struct list_head *head)
Definition: list.h:216
static void __list_del(struct list_head *prev, struct list_head *next)
Definition: list.h:75
static void list_replace_init(struct list_head *old, struct list_head *new)
Definition: list.h:103
static int list_is_first(const struct list_head *list, const struct list_head *head)
Definition: list.h:319
static void linux_list_add(struct list_head *new, struct list_head *prev, struct list_head *next)
Definition: list.h:110
static void list_replace(struct list_head *old, struct list_head *new)
Definition: list.h:94
static int list_is_singular(const struct list_head *head)
Definition: list.h:288
static void list_add_tail(struct list_head *new, struct list_head *head)
Definition: list.h:203
static int list_empty(const struct list_head *head)
Definition: list.h:61
static void linux_list_splice(const struct list_head *list, struct list_head *prev, struct list_head *next)
Definition: list.h:241
static void list_cut_position(struct list_head *list, struct list_head *head, struct list_head *entry)
Definition: list.h:305
#define list_for_each(p, head)
Definition: list.h:149
static void list_splice_init(struct list_head *list, struct list_head *head)
Definition: list.h:270
static size_t list_count_nodes(const struct list_head *list)
Definition: list.h:332
static void __list_del_entry(struct list_head *entry)
Definition: list.h:82
static void list_del(struct list_head *entry)
Definition: list.h:88
static int list_empty_careful(const struct list_head *head)
Definition: list.h:67
static void list_rotate_to_front(struct list_head *entry, struct list_head *head)
Definition: list.h:223
static int list_is_last(const struct list_head *list, const struct list_head *head)
Definition: list.h:325
static void list_rotate_left(struct list_head *h)
list_rotate_left - rotate the list to the left
Definition: list.h:368
static void list_del_init(struct list_head *entry)
Definition: list.h:123
static void list_splice_tail(struct list_head *list, struct list_head *head)
Definition: list.h:264
static void INIT_LIST_HEAD(struct list_head *list)
Definition: list.h:54
static void list_move(struct list_head *list, struct list_head *head)
Definition: list.h:209
static uint32_t lh(unsigned int rd, unsigned int base, uint16_t offset) __attribute__((unused))
Definition: opcodes.h:117
Definition: list.h:41
struct list_head * next
Definition: list.h:42
struct list_head * prev
Definition: list.h:43
uint8_t count[4]
Definition: vdebug.c:22