T-Box Basic dev
Loading...
Searching...
No Matches
list.h
Go to the documentation of this file.
1
10
11#ifndef __TBOX_LIST_H__
12#define __TBOX_LIST_H__
13
14#include <stddef.h>
15
16#define tbox_typeof(x) __typeof__(x)
17
18#ifdef __cplusplus
19extern "C"
20{
21#endif
22
28
34static inline void prefetch(const void* x)
35{
36 (void)x;
37}
38
44static inline void prefetchw(const void* x)
45{
46 (void)x;
47}
48
49#define LIST_POISON1 ((void*)0x00100100)
50#define LIST_POISON2 ((void*)0x00200200)
51
57typedef struct list_node
58{
59 struct list_node* next;
60 struct list_node* prev;
62
68#define DLIST_HEAD_IN_STRUCT_INIT(field) \
69 do \
70 { \
71 (field).next = &(field); \
72 (field).prev = &(field); \
73 } while (0)
74
80#define DLIST_HEAD_INIT(name) {&(name), &(name)}
81
87#define DLIST_HEAD(name) struct list_node name = DLIST_HEAD_INIT(name)
88
94static inline void INIT_LIST_HEAD(struct list_node* list)
95{
96 list->next = list;
97 list->prev = list;
98}
99
106static inline int list_empty(const struct list_node* head)
107{
108 return ((head->next == head) && (head->prev == head));
109}
110
117static inline void list_append(struct list_node* new_node, struct list_node* existing)
118{
119 existing->next->prev = new_node;
120 new_node->next = existing->next;
121 new_node->prev = existing;
122 existing->next = new_node;
123}
124
131static inline void list_prepend(struct list_node* new_node, struct list_node* existing)
132{
133 existing->prev->next = new_node;
134 new_node->next = existing;
135 new_node->prev = existing->prev;
136 existing->prev = new_node;
137}
138
148static inline void __list_add(struct list_node* new_node, struct list_node* prev, struct list_node* next)
149{
150 next->prev = new_node;
151 new_node->next = next;
152 new_node->prev = prev;
153 prev->next = new_node;
154}
155
164static inline void list_add(struct list_node* new_node, struct list_node* head)
165{
166 __list_add(new_node, head, head->next);
167}
168
177static inline void list_add_tail(struct list_node* new_node, struct list_node* head)
178{
179 __list_add(new_node, head->prev, head);
180}
181
187static inline void list_unlink(struct list_node* entry)
188{
189 entry->next->prev = entry->prev;
190 entry->prev->next = entry->next;
191 entry->next = NULL;
192 entry->prev = NULL;
193}
194
203static inline void __list_del(struct list_node* prev, struct list_node* next)
204{
205 next->prev = prev;
206 prev->next = next;
207}
208
216static inline void list_del(struct list_node* list)
217{
218 __list_del(list->prev, list->next);
219}
220
228#define container_of(ptr, type, member) \
229 ({ \
230 const tbox_typeof(((type*)0)->member)* __mptr = (ptr); \
231 (type*)((char*)__mptr - offsetof(type, member)); \
232 })
233
241#define list_entry(ptr, type, member) container_of(ptr, type, member)
242
251#define list_for_each(pos, head) for (pos = (head)->next; prefetch(pos->next), pos != (head); pos = pos->next)
252
262#define list_for_each_entry(pos, head, member) \
263 for (pos = list_entry((head)->next, tbox_typeof(*pos), member); &pos->member != (head); \
264 pos = list_entry(pos->member.next, tbox_typeof(*pos), member))
265
276#define list_for_each_entry_safe(pos, n, head, member) \
277 for (pos = list_entry((head)->next, tbox_typeof(*pos), member), \
278 n = list_entry(pos->member.next, tbox_typeof(*pos), member); \
279 &pos->member != (head); pos = n, n = list_entry(n->member.next, tbox_typeof(*n), member))
280
287{
288 struct hlist_node* first;
289};
290
297{
298 struct hlist_node* next;
299 struct hlist_node** pprev;
300};
301
305#define HLIST_HEAD_INIT {.first = NULL}
306
312#define HLIST_HEAD(name) struct hlist_head name = {.first = NULL}
313
319#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
320
326#define INIT_HLIST_NODE(ptr) \
327 do \
328 { \
329 (ptr)->next = NULL; \
330 (ptr)->pprev = NULL; \
331 } while (0)
332
339static inline int hlist_unhashed(const struct hlist_node* h)
340{
341 return !h->pprev;
342}
343
350static inline int hlist_empty(const struct hlist_head* h)
351{
352 return !h->first;
353}
354
362static inline void __hlist_del(struct hlist_node* n)
363{
364 struct hlist_node* next = n->next;
365 struct hlist_node** pprev = n->pprev;
366
367 *pprev = next;
368 if (next)
369 {
370 next->pprev = pprev;
371 }
372}
373
381static inline void hlist_del(struct hlist_node* n)
382{
383 __hlist_del(n);
384 n->next = (struct hlist_node*)LIST_POISON1;
385 n->pprev = (struct hlist_node**)LIST_POISON2;
386}
387
393static inline void hlist_del_init(struct hlist_node* n)
394{
395 if (n->pprev)
396 {
397 __hlist_del(n);
399 }
400}
401
408static inline void hlist_add_head(struct hlist_node* n, struct hlist_head* h)
409{
410 struct hlist_node* first = h->first;
411
412 n->next = first;
413 if (first)
414 {
415 first->pprev = &n->next;
416 }
417 h->first = n;
418 n->pprev = &h->first;
419}
420
427static inline void hlist_add_before(struct hlist_node* n, struct hlist_node* next)
428{
429 n->pprev = next->pprev;
430 n->next = next;
431 next->pprev = &n->next;
432 *(n->pprev) = n;
433}
434
443static inline void hlist_add_after(struct hlist_node* n, struct hlist_node* next)
444{
445 next->next = n->next;
446 n->next = next;
447 next->pprev = &n->next;
448 if (next->next)
449 {
450 next->next->pprev = &next->next;
451 }
452}
453
461#define hlist_entry(ptr, type, member) container_of(ptr, type, member)
462
471#define hlist_for_each(pos, head) \
472 for (pos = (head)->first; pos && ({ \
473 prefetch(pos->next); \
474 1; \
475 }); \
476 pos = pos->next)
477
487#define hlist_for_each_safe(pos, n, head) \
488 for (pos = (head)->first; pos && ({ \
489 n = pos->next; \
490 1; \
491 }); \
492 pos = n)
493
504#define hlist_for_each_entry(tpos, pos, head, member) \
505 for (pos = (head)->first; pos && ({ \
506 prefetch(pos->next); \
507 1; \
508 }) && \
509 ({ \
510 tpos = hlist_entry(pos, tbox_typeof(*tpos), member); \
511 1; \
512 }); \
513 pos = pos->next)
514
522#define hlist_for_each_entry_continue(tpos, pos, member) \
523 for (pos = (pos)->next; pos && ({ \
524 prefetch(pos->next); \
525 1; \
526 }) && \
527 ({ \
528 tpos = hlist_entry(pos, tbox_typeof(*tpos), member); \
529 1; \
530 }); \
531 pos = pos->next)
532
540#define hlist_for_each_entry_from(tpos, pos, member) \
541 for (; pos && ({ \
542 prefetch(pos->next); \
543 1; \
544 }) && \
545 ({ \
546 tpos = hlist_entry(pos, tbox_typeof(*tpos), member); \
547 1; \
548 }); \
549 pos = pos->next)
550
562#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
563 for (pos = (head)->first; pos && ({ \
564 n = pos->next; \
565 1; \
566 }) && \
567 ({ \
568 tpos = hlist_entry(pos, tbox_typeof(*tpos), member); \
569 1; \
570 }); \
571 pos = n)
572
576
577#ifdef __cplusplus
578}
579#endif
580
581#endif /* __TBOX_LIST_H__ */
#define LIST_POISON2
链表删除后的 prev/pprev poison 值。
Definition list.h:50
struct list_node list_node_t
双向循环链表节点。
#define LIST_POISON1
链表删除后的 next poison 值。
Definition list.h:49
#define INIT_HLIST_NODE(ptr)
初始化 hlist 节点为未挂链状态。
Definition list.h:326
hlist 链表头。
Definition list.h:287
hlist 节点。
Definition list.h:297
双向循环链表节点。
Definition list.h:58
struct list_node * next
下一个节点。
Definition list.h:59
struct list_node * prev
前一个节点。
Definition list.h:60