VSF Documented
list.h
Go to the documentation of this file.
1#ifndef __VSF_LINUX_LIST_H__
2#define __VSF_LINUX_LIST_H__
3
4#include <linux/types.h>
5
6#ifdef __cplusplus
7extern "C" {
8#endif
9
10#define LIST_HEAD_INIT(__NAME) { &(__NAME), &(__NAME) }
11#define LIST_HEAD(__NAME) struct list_head __NAME = LIST_HEAD_INIT(__NAME)
12
13#define list_entry(ptr, type, member) vsf_container_of(ptr, type, member)
14#define list_first_entry(ptr, type, member) list_entry((ptr)->next, type, member)
15#define list_last_entry(ptr, type, member) list_entry((ptr)->prev, type, member)
16#define list_next_entry(pos, member) list_entry((pos)->member.next, typeof(*(pos)), member)
17#define list_next_entry_circular(pos, head, member) \
18 (list_is_last(&(pos)->member, head) ? list_first_entry(head, typeof(*(pos)), member) : list_next_entry(pos, member))
19#define list_prev_entry(pos, member) list_entry((pos)->member.prev, typeof(*(pos)), member)
20#define list_prev_entry_circular(pos, head, member) \
21 (list_is_first(&(pos)->member, head) ? list_last_entry(head, typeof(*(pos)), member) : list_prev_entry(pos, member))
22#define list_first_entry_or_null(ptr, type, member) ({ \
23 struct list_head *head__ = (ptr); \
24 struct list_head *pos__ = READ_ONCE(head__->next); \
25 pos__ != head__ ? list_entry(pos__, type, member) : NULL; \
26})
27#define list_entry_is_head(pos, head, member) (&pos->member == (head))
28
29#define list_prepare_entry(pos, head, member) ((pos) ? : list_entry(head, typeof(*pos), member))
30
31#define list_for_each(pos, head) for (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next)
32#define list_for_each_continue(pos, head) for (pos = pos->next; !list_is_head(pos, (head)); pos = pos->next)
33#define list_for_each_prev(pos, head) for (pos = (head)->prev; !list_is_head(pos, (head)); pos = pos->prev)
34#define list_for_each_safe(pos, n, head) \
35 for (pos = (head)->next, n = pos->next; !list_is_head(pos, (head)); pos = n, n = pos->next)
36#define list_for_each_prev_safe(pos, n, head) \
37 for (pos = (head)->prev, n = pos->prev; !list_is_head(pos, (head)); pos = n, n = pos->prev)
38#define list_for_each_entry(pos, head, member) \
39 for (pos = list_first_entry(head, typeof(*pos), member); \
40 !list_entry_is_head(pos, head, member); \
41 pos = list_next_entry(pos, member))
42#define list_for_each_entry_reverse(pos, head, member) \
43 for (pos = list_last_entry(head, typeof(*pos), member); \
44 !list_entry_is_head(pos, head, member); \
45 pos = list_prev_entry(pos, member))
46#define list_for_each_entry_continue(pos, head, member) \
47 for (pos = list_next_entry(pos, member); \
48 !list_entry_is_head(pos, head, member); \
49 pos = list_next_entry(pos, member))
50#define list_for_each_entry_continue_reverse(pos, head, member) \
51 for (pos = list_prev_entry(pos, member); \
52 !list_entry_is_head(pos, head, member); \
53 pos = list_prev_entry(pos, member))
54#define list_for_each_entry_from(pos, head, member) \
55 for (; !list_entry_is_head(pos, head, member); pos = list_next_entry(pos, member))
56#define list_for_each_entry_from_reverse(pos, head, member) \
57 for (; !list_entry_is_head(pos, head, member); pos = list_prev_entry(pos, member))
58#define list_for_each_entry_safe(pos, n, head, member) \
59 for (pos = list_first_entry(head, typeof(*pos), member), \
60 n = list_next_entry(pos, member); \
61 !list_entry_is_head(pos, head, member); \
62 pos = n, n = list_next_entry(n, member))
63#define list_for_each_entry_safe_continue(pos, n, head, member) \
64 for (pos = list_next_entry(pos, member), n = list_next_entry(pos, member); \
65 !list_entry_is_head(pos, head, member); \
66 pos = n, n = list_next_entry(n, member))
67#define list_for_each_entry_safe_from(pos, n, head, member) \
68 for (n = list_next_entry(pos, member); \
69 !list_entry_is_head(pos, head, member); \
70 pos = n, n = list_next_entry(n, member))
71#define list_for_each_entry_safe_reverse(pos, n, head, member) \
72 for (pos = list_last_entry(head, typeof(*pos), member), \
73 n = list_prev_entry(pos, member); \
74 !list_entry_is_head(pos, head, member); \
75 pos = n, n = list_prev_entry(n, member))
76
77struct list_head {
78 struct list_head *next, *prev;
79};
80
81static inline void INIT_LIST_HEAD(struct list_head *list)
82{
83 list->next = list;
84 list->prev = list;
85}
86
87static inline int list_is_head(const struct list_head *list, const struct list_head *head)
88{
89 return list == head;
90}
91
92static inline int list_is_last(const struct list_head *list, const struct list_head *head)
93{
94 return list->next == head;
95}
96
97static inline int list_empty(const struct list_head *head)
98{
99 return head->next == head;
100}
101
102static inline int list_is_singular(const struct list_head *head)
103{
104 return !list_empty(head) && (head->next == head->prev);
105}
106
107static inline void list_insert(struct list_head *node, struct list_head *prev, struct list_head *next)
108{
109 next->prev = node;
110 node->next = next;
111 node->prev = prev;
112 prev->next = node;
113}
114
115static inline void list_add(struct list_head *node, struct list_head *head)
116{
117 list_insert(node, head, head->next);
118}
119
120static inline void list_add_tail(struct list_head *node, struct list_head *head)
121{
122 list_insert(node, head->prev, head);
123}
124
125static inline void list_del(struct list_head *entry)
126{
127 entry->next->prev = entry->prev;
128 entry->prev->next = entry->next;
129}
130
131static inline void list_del_init(struct list_head *entry)
132{
133 list_del(entry);
134 INIT_LIST_HEAD(entry);
135}
136
137#ifdef __cplusplus
138}
139#endif
140
141#endif
Definition list.h:77
struct list_head * prev
Definition list.h:78
struct list_head * next
Definition list.h:78
vsf_msgt_node_offset_t next
Definition vsf_msg_tree.h:192
uint16_t head
Definition vsf_queue.h:632