Line data Source code
1 : /* $OpenBSD: drm_linux_list.h,v 1.8 2018/01/31 04:35:38 jsg Exp $ */
2 : /* drm_linux_list.h -- linux list functions for the BSDs.
3 : * Created: Mon Apr 7 14:30:16 1999 by anholt@FreeBSD.org
4 : */
5 : /*-
6 : * Copyright 2003 Eric Anholt
7 : * All Rights Reserved.
8 : *
9 : * Permission is hereby granted, free of charge, to any person obtaining a
10 : * copy of this software and associated documentation files (the "Software"),
11 : * to deal in the Software without restriction, including without limitation
12 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 : * and/or sell copies of the Software, and to permit persons to whom the
14 : * Software is furnished to do so, subject to the following conditions:
15 : *
16 : * The above copyright notice and this permission notice (including the next
17 : * paragraph) shall be included in all copies or substantial portions of the
18 : * Software.
19 : *
20 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 : * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 : * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 : * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26 : * OTHER DEALINGS IN THE SOFTWARE.
27 : *
28 : * Authors:
29 : * Eric Anholt <anholt@FreeBSD.org>
30 : *
31 : */
32 :
33 : #ifndef _DRM_LINUX_LIST_H_
34 : #define _DRM_LINUX_LIST_H_
35 :
36 : struct list_head {
37 : struct list_head *next, *prev;
38 : };
39 :
40 : #define list_entry(ptr, type, member) container_of(ptr, type, member)
41 :
42 : static inline void
43 0 : INIT_LIST_HEAD(struct list_head *head) {
44 0 : (head)->next = head;
45 0 : (head)->prev = head;
46 0 : }
47 :
48 : #define LIST_HEAD_INIT(name) { &(name), &(name) }
49 :
50 : #define DRM_LIST_HEAD(name) \
51 : struct list_head name = LIST_HEAD_INIT(name)
52 :
53 : static inline int
54 0 : list_empty(const struct list_head *head) {
55 0 : return (head)->next == head;
56 : }
57 :
58 : static inline int
59 : list_is_singular(const struct list_head *head) {
60 : return !list_empty(head) && ((head)->next == (head)->prev);
61 : }
62 :
63 : static inline void
64 0 : list_add(struct list_head *new, struct list_head *head) {
65 0 : (head)->next->prev = new;
66 0 : (new)->next = (head)->next;
67 0 : (new)->prev = head;
68 0 : (head)->next = new;
69 0 : }
70 :
71 : static inline void
72 0 : list_add_tail(struct list_head *entry, struct list_head *head) {
73 0 : (entry)->prev = (head)->prev;
74 0 : (entry)->next = head;
75 0 : (head)->prev->next = entry;
76 0 : (head)->prev = entry;
77 0 : }
78 :
79 : static inline void
80 0 : list_del(struct list_head *entry) {
81 0 : (entry)->next->prev = (entry)->prev;
82 0 : (entry)->prev->next = (entry)->next;
83 0 : }
84 :
85 0 : static inline void list_replace(struct list_head *old,
86 : struct list_head *new)
87 : {
88 0 : new->next = old->next;
89 0 : new->next->prev = new;
90 0 : new->prev = old->prev;
91 0 : new->prev->next = new;
92 0 : }
93 :
94 0 : static inline void list_replace_init(struct list_head *old,
95 : struct list_head *new)
96 : {
97 0 : list_replace(old, new);
98 0 : INIT_LIST_HEAD(old);
99 0 : }
100 :
101 0 : static inline void list_move(struct list_head *list, struct list_head *head)
102 : {
103 0 : list_del(list);
104 0 : list_add(list, head);
105 0 : }
106 :
107 0 : static inline void list_move_tail(struct list_head *list,
108 : struct list_head *head)
109 : {
110 0 : list_del(list);
111 0 : list_add_tail(list, head);
112 0 : }
113 :
114 : static inline void
115 0 : list_del_init(struct list_head *entry) {
116 0 : (entry)->next->prev = (entry)->prev;
117 0 : (entry)->prev->next = (entry)->next;
118 0 : INIT_LIST_HEAD(entry);
119 0 : }
120 :
121 : #define list_next_entry(pos, member) \
122 : list_entry(((pos)->member.next), typeof(*(pos)), member)
123 :
124 : #define list_prev_entry(pos, member) \
125 : list_entry(((pos)->member.prev), typeof(*(pos)), member)
126 :
127 : #define list_for_each(entry, head) \
128 : for (entry = (head)->next; entry != head; entry = (entry)->next)
129 :
130 : #define list_for_each_prev(entry, head) \
131 : for (entry = (head)->prev; entry != (head); \
132 : entry = entry->prev)
133 :
134 : #define list_for_each_safe(entry, temp, head) \
135 : for (entry = (head)->next, temp = (entry)->next; \
136 : entry != head; \
137 : entry = temp, temp = entry->next)
138 :
139 : #define list_for_each_entry_safe_from(pos, n, head, member) \
140 : for (n = list_entry(pos->member.next, __typeof(*pos), member); \
141 : &pos->member != (head); \
142 : pos = n, n = list_entry(n->member.next, __typeof(*n), member))
143 :
144 : #define list_for_each_entry(pos, head, member) \
145 : for (pos = list_entry((head)->next, __typeof(*pos), member); \
146 : &pos->member != (head); \
147 : pos = list_entry(pos->member.next, __typeof(*pos), member))
148 :
149 : #define list_for_each_entry_continue(pos, head, member) \
150 : for (pos = list_entry((pos)->member.next, __typeof(*pos), member); \
151 : &pos->member != (head); \
152 : pos = list_entry(pos->member.next, __typeof(*pos), member))
153 :
154 : #define list_for_each_entry_continue_reverse(pos, head, member) \
155 : for (pos = list_entry(pos->member.prev, __typeof(*pos), member); \
156 : &pos->member != (head); \
157 : pos = list_entry(pos->member.prev, __typeof(*pos), member))
158 :
159 : /**
160 : * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
161 : * @pos: the type * to use as a loop cursor.
162 : * @n: another type * to use as temporary storage
163 : * @head: the head for your list.
164 : * @member: the name of the list_struct within the struct.
165 : */
166 : #define list_for_each_entry_safe(pos, n, head, member) \
167 : for (pos = list_entry((head)->next, __typeof(*pos), member), \
168 : n = list_entry(pos->member.next, __typeof(*pos), member); \
169 : &pos->member != (head); \
170 : pos = n, n = list_entry(n->member.next, __typeof(*n), member))
171 :
172 : #define list_first_entry(ptr, type, member) \
173 : list_entry((ptr)->next, type, member)
174 :
175 : #define list_first_entry_or_null(ptr, type, member) \
176 : (list_empty(ptr) ? NULL : list_first_entry(ptr, type, member))
177 :
178 : #define list_last_entry(ptr, type, member) \
179 : list_entry((ptr)->prev, type, member)
180 :
181 : static inline void
182 0 : __list_splice(const struct list_head *list, struct list_head *prev,
183 : struct list_head *next)
184 : {
185 0 : struct list_head *first = list->next;
186 0 : struct list_head *last = list->prev;
187 :
188 0 : first->prev = prev;
189 0 : prev->next = first;
190 :
191 0 : last->next = next;
192 0 : next->prev = last;
193 0 : }
194 :
195 : static inline void
196 0 : list_splice(const struct list_head *list, struct list_head *head)
197 : {
198 0 : if (list_empty(list))
199 : return;
200 :
201 0 : __list_splice(list, head, head->next);
202 0 : }
203 :
204 : static inline void
205 0 : list_splice_tail(const struct list_head *list, struct list_head *head)
206 : {
207 0 : if (list_empty(list))
208 : return;
209 :
210 0 : __list_splice(list, head->prev, head);
211 0 : }
212 :
213 : void list_sort(void *, struct list_head *,
214 : int (*)(void *, struct list_head *, struct list_head *));
215 :
216 : struct hlist_node {
217 : struct hlist_node *next, **prev;
218 : };
219 :
220 : struct hlist_head {
221 : struct hlist_node *first;
222 : };
223 :
224 : #define hlist_entry(ptr, type, member) \
225 : ((ptr) ? container_of(ptr, type, member) : NULL)
226 :
227 : static inline void
228 0 : INIT_HLIST_HEAD(struct hlist_head *head) {
229 0 : head->first = NULL;
230 0 : }
231 :
232 : static inline int
233 0 : hlist_empty(const struct hlist_head *head) {
234 0 : return head->first == NULL;
235 : }
236 :
237 : static inline void
238 0 : hlist_add_head(struct hlist_node *new, struct hlist_head *head)
239 : {
240 0 : if ((new->next = head->first) != NULL)
241 0 : head->first->prev = &new->next;
242 0 : head->first = new;
243 0 : new->prev = &head->first;
244 0 : }
245 :
246 : static inline void
247 0 : hlist_del_init(struct hlist_node *node)
248 : {
249 0 : if (node->next != NULL)
250 0 : node->next->prev = node->prev;
251 0 : *(node->prev) = node->next;
252 0 : node->next = NULL;
253 0 : node->prev = NULL;
254 0 : }
255 :
256 : #define hlist_for_each(pos, head) \
257 : for (pos = (head)->first; pos != NULL; pos = pos->next)
258 :
259 : #define hlist_for_each_entry(pos, head, member) \
260 : for (pos = hlist_entry((head)->first, __typeof(*pos), member); \
261 : pos != NULL; \
262 : pos = hlist_entry((pos)->member.next, __typeof(*pos), member))
263 :
264 : #define hlist_for_each_entry_safe(pos, n, head, member) \
265 : for (pos = hlist_entry((head)->first, __typeof(*pos), member); \
266 : pos != NULL && (n = pos->member.next, 1); \
267 : pos = hlist_entry(n, __typeof(*pos), member))
268 :
269 : #endif /* _DRM_LINUX_LIST_H_ */
|