Xenomai 3.3.2
Loading...
Searching...
No Matches
private-list.h
1/*
2 * Copyright (C) 2010 Philippe Gerum <rpm@xenomai.org>.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17 */
18
19#ifndef _BOILERPLATE_PRIVATE_LIST_H
20#define _BOILERPLATE_PRIVATE_LIST_H
21
22#ifndef _BOILERPLATE_LIST_H
23#error "Do not include this file directly. Use <boilerplate/list.h> instead."
24#endif
25
26struct pvholder {
27 struct pvholder *next;
28 struct pvholder *prev;
29};
30
31struct pvlistobj {
32 struct pvholder head;
33};
34
35#define PRIVATE_LIST_INITIALIZER(__name) \
36 { .head = { .next = &((__name).head), .prev = &((__name).head) } }
37
38#define DEFINE_PRIVATE_LIST(__name) \
39 struct pvlistobj __name = PRIVATE_LIST_INITIALIZER(__name)
40
41static inline void initpvh(struct pvholder *holder)
42{
43 holder->next = holder;
44 holder->prev = holder;
45}
46
47static inline void atpvh(struct pvholder *head, struct pvholder *holder)
48{
49 /* Inserts the new element right after the heading one. */
50 holder->prev = head;
51 holder->next = head->next;
52 holder->next->prev = holder;
53 head->next = holder;
54}
55
56static inline void dtpvh(struct pvholder *holder)
57{
58 holder->prev->next = holder->next;
59 holder->next->prev = holder->prev;
60}
61
62static inline void pvlist_init(struct pvlistobj *list)
63{
64 initpvh(&list->head);
65}
66
67static inline void pvholder_init(struct pvholder *holder)
68{
69 initpvh(holder);
70}
71
72/*
73 * XXX: pvholder_init() is mandatory if you later want to use this
74 * predicate.
75 */
76static inline int pvholder_linked(const struct pvholder *holder)
77{
78 return !(holder->prev == holder->next &&
79 holder->prev == holder);
80}
81
82static inline void pvlist_prepend(struct pvholder *holder, struct pvlistobj *list)
83{
84 atpvh(&list->head, holder);
85}
86
87static inline void pvlist_append(struct pvholder *holder, struct pvlistobj *list)
88{
89 atpvh(list->head.prev, holder);
90}
91
92static inline void pvlist_insert(struct pvholder *next, struct pvholder *prev)
93{
94 atpvh(prev, next);
95}
96
97static inline void pvlist_join(struct pvlistobj *lsrc, struct pvlistobj *ldst)
98{
99 struct pvholder *headsrc = lsrc->head.next;
100 struct pvholder *tailsrc = lsrc->head.prev;
101 struct pvholder *headdst = &ldst->head;
102
103 headsrc->prev->next = tailsrc->next;
104 tailsrc->next->prev = headsrc->prev;
105 headsrc->prev = headdst;
106 tailsrc->next = headdst->next;
107 headdst->next->prev = tailsrc;
108 headdst->next = headsrc;
109}
110
111static inline void pvlist_remove(struct pvholder *holder)
112{
113 dtpvh(holder);
114}
115
116static inline void pvlist_remove_init(struct pvholder *holder)
117{
118 dtpvh(holder);
119 initpvh(holder);
120}
121
122static inline int pvlist_empty(const struct pvlistobj *list)
123{
124 return list->head.next == &list->head;
125}
126
127static inline struct pvholder *pvlist_pop(struct pvlistobj *list)
128{
129 struct pvholder *holder = list->head.next;
130 pvlist_remove(holder);
131 return holder;
132}
133
134static inline int pvlist_heading_p(const struct pvholder *holder,
135 const struct pvlistobj *list)
136{
137 return list->head.next == holder;
138}
139
140#define pvlist_entry(ptr, type, member) \
141 container_of(ptr, type, member)
142
143#define pvlist_first_entry(list, type, member) \
144 pvlist_entry((list)->head.next, type, member)
145
146#define pvlist_last_entry(list, type, member) \
147 pvlist_entry((list)->head.prev, type, member)
148
149#define pvlist_prev_entry(pos, list, member) \
150 ({ \
151 typeof(*pos) *__prev = NULL; \
152 if ((list)->head.next != &(pos)->member) \
153 __prev = pvlist_entry((pos)->member.prev, \
154 typeof(*pos), member); \
155 __prev; \
156 })
157
158#define pvlist_next_entry(pos, list, member) \
159 ({ \
160 typeof(*pos) *__next = NULL; \
161 if ((list)->head.prev != &(pos)->member) \
162 __next = pvlist_entry((pos)->member.next, \
163 typeof(*pos), member); \
164 __next; \
165 })
166
167#define pvlist_pop_entry(list, type, member) ({ \
168 struct pvholder *__holder = pvlist_pop(list); \
169 pvlist_entry(__holder, type, member); })
170
171#define pvlist_for_each(pos, list) \
172 for (pos = (list)->head.next; \
173 pos != &(list)->head; pos = (pos)->next)
174
175#define pvlist_for_each_reverse(pos, list) \
176 for (pos = (list)->head.prev; \
177 pos != &(list)->head; pos = (pos)->prev)
178
179#define pvlist_for_each_safe(pos, tmp, list) \
180 for (pos = (list)->head.next, \
181 tmp = (pos)->next; \
182 pos != &(list)->head; \
183 pos = tmp, tmp = (pos)->next)
184
185#define pvlist_for_each_entry(pos, list, member) \
186 for (pos = pvlist_entry((list)->head.next, \
187 typeof(*pos), member); \
188 &(pos)->member != &(list)->head; \
189 pos = pvlist_entry((pos)->member.next, \
190 typeof(*pos), member))
191
192#define pvlist_for_each_entry_safe(pos, tmp, list, member) \
193 for (pos = pvlist_entry((list)->head.next, \
194 typeof(*pos), member), \
195 tmp = pvlist_entry((pos)->member.next, \
196 typeof(*pos), member); \
197 &(pos)->member != &(list)->head; \
198 pos = tmp, tmp = pvlist_entry((pos)->member.next, \
199 typeof(*pos), member))
200
201#define pvlist_for_each_entry_reverse(pos, list, member) \
202 for (pos = pvlist_entry((list)->head.prev, \
203 typeof(*pos), member); \
204 &pos->member != &(list)->head; \
205 pos = pvlist_entry(pos->member.prev, \
206 typeof(*pos), member))
207
208#define pvlist_for_each_entry_reverse_safe(pos, tmp, list, member) \
209 for (pos = pvlist_entry((list)->head.prev, \
210 typeof(*pos), member), \
211 tmp = pvlist_entry((pos)->member.prev, \
212 typeof(*pos), member); \
213 &(pos)->member != &(list)->head; \
214 pos = tmp, tmp = pvlist_entry((pos)->member.prev, \
215 typeof(*pos), member))
216
217#endif /* !_BOILERPLATE_PRIVATE_LIST_H */