libubox
C utility functions for OpenWrt.
list.h
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org>
3  * Copyright (c) 2010 Isilon Systems, Inc.
4  * Copyright (c) 2010 iX Systems, Inc.
5  * Copyright (c) 2010 Panasas, Inc.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  * notice unmodified, this list of conditions, and the following
13  * disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 #ifndef _LINUX_LIST_H_
30 #define _LINUX_LIST_H_
31 
32 #include <stddef.h>
33 #include <stdbool.h>
34 
35 #define prefetch(x)
36 
37 #ifndef container_of
38 #define container_of(ptr, type, member) \
39  ({ \
40  const __typeof__(((type *) NULL)->member) *__mptr = (ptr); \
41  (type *) ((char *) __mptr - offsetof(type, member)); \
42  })
43 #endif
44 
45 #ifndef container_of_safe
46 #define container_of_safe(ptr, type, member) \
47  ({ \
48  const __typeof__(((type *) NULL)->member) *__mptr = (ptr); \
49  __mptr ? (type *)((char *) __mptr - offsetof(type, member)) : NULL; \
50  })
51 #endif
52 
53 struct list_head {
54  struct list_head *next;
55  struct list_head *prev;
56 };
57 
58 #define LIST_HEAD_INIT(name) { &(name), &(name) }
59 #undef LIST_HEAD
60 #define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)
61 
62 static inline void
64 {
65  list->next = list->prev = list;
66 }
67 
68 static inline bool
69 list_empty(const struct list_head *head)
70 {
71  return (head->next == head);
72 }
73 
74 static inline bool
75 list_is_first(const struct list_head *list,
76  const struct list_head *head)
77 {
78  return list->prev == head;
79 }
80 
81 static inline bool
82 list_is_last(const struct list_head *list,
83  const struct list_head *head)
84 {
85  return list->next == head;
86 }
87 
88 static inline void
89 _list_del(struct list_head *entry)
90 {
91  entry->next->prev = entry->prev;
92  entry->prev->next = entry->next;
93 }
94 
95 static inline void
96 list_del(struct list_head *entry)
97 {
98  _list_del(entry);
99  entry->next = entry->prev = NULL;
100 }
101 
102 static inline void
103 _list_add(struct list_head *_new, struct list_head *prev,
104  struct list_head *next)
105 {
106 
107  next->prev = _new;
108  _new->next = next;
109  _new->prev = prev;
110  prev->next = _new;
111 }
112 
113 static inline void
114 list_del_init(struct list_head *entry)
115 {
116  _list_del(entry);
117  INIT_LIST_HEAD(entry);
118 }
119 
120 #define list_entry(ptr, type, field) container_of(ptr, type, field)
121 #define list_first_entry(ptr, type, field) list_entry((ptr)->next, type, field)
122 #define list_last_entry(ptr, type, field) list_entry((ptr)->prev, type, field)
123 #define list_next_entry(pos, member) list_entry((pos)->member.next, typeof(*(pos)), member)
124 #define list_entry_is_h(p, h, field) (&p->field == (h))
125 
126 #define list_for_each(p, head) \
127  for (p = (head)->next; p != (head); p = p->next)
128 
129 #define list_for_each_safe(p, n, head) \
130  for (p = (head)->next, n = p->next; p != (head); p = n, n = p->next)
131 
132 #define list_for_each_entry(p, h, field) \
133  for (p = list_first_entry(h, __typeof__(*p), field); &p->field != (h); \
134  p = list_entry(p->field.next, __typeof__(*p), field))
135 
136 #define list_for_each_entry_continue(p, h, field) \
137  for (p = list_next_entry(p, field); \
138  !list_entry_is_h(p, h, field); \
139  p = list_next_entry(p, field))
140 
141 #define list_for_each_entry_continue_reverse(p, h, field) \
142  for (p = list_prev_entry(p, field); \
143  !list_entry_is_h(p, h, field); \
144  p = list_prev_entry(p, field))
145 
146 #define list_for_each_entry_safe(p, n, h, field) \
147  for (p = list_first_entry(h, __typeof__(*p), field), \
148  n = list_entry(p->field.next, __typeof__(*p), field); &p->field != (h);\
149  p = n, n = list_entry(n->field.next, __typeof__(*n), field))
150 
151 #define list_for_each_entry_reverse(p, h, field) \
152  for (p = list_last_entry(h, __typeof__(*p), field); &p->field != (h); \
153  p = list_entry(p->field.prev, __typeof__(*p), field))
154 
155 #define list_for_each_prev(p, h) for (p = (h)->prev; p != (h); p = p->prev)
156 #define list_for_each_prev_safe(p, n, h) for (p = (h)->prev, n = p->prev; p != (h); p = n, n = p->prev)
157 
158 static inline void
159 list_add(struct list_head *_new, struct list_head *head)
160 {
161  _list_add(_new, head, head->next);
162 }
163 
164 static inline void
165 list_add_tail(struct list_head *_new, struct list_head *head)
166 {
167  _list_add(_new, head->prev, head);
168 }
169 
170 static inline void
171 list_move(struct list_head *list, struct list_head *head)
172 {
173  _list_del(list);
174  list_add(list, head);
175 }
176 
177 static inline void
178 list_move_tail(struct list_head *entry, struct list_head *head)
179 {
180  _list_del(entry);
181  list_add_tail(entry, head);
182 }
183 
184 static inline void
185 _list_splice(const struct list_head *list, struct list_head *prev,
186  struct list_head *next)
187 {
188  struct list_head *first;
189  struct list_head *last;
190 
191  if (list_empty(list))
192  return;
193 
194  first = list->next;
195  last = list->prev;
196  first->prev = prev;
197  prev->next = first;
198  last->next = next;
199  next->prev = last;
200 }
201 
202 static inline void
203 list_splice(const struct list_head *list, struct list_head *head)
204 {
205  _list_splice(list, head, head->next);
206 }
207 
208 static inline void
209 list_splice_tail(struct list_head *list, struct list_head *head)
210 {
211  _list_splice(list, head->prev, head);
212 }
213 
214 static inline void
215 list_splice_init(struct list_head *list, struct list_head *head)
216 {
217  _list_splice(list, head, head->next);
218  INIT_LIST_HEAD(list);
219 }
220 
221 static inline void
222 list_splice_tail_init(struct list_head *list, struct list_head *head)
223 {
224  _list_splice(list, head->prev, head);
225  INIT_LIST_HEAD(list);
226 }
227 
228 #endif /* _LINUX_LIST_H_ */
static void list_splice(const struct list_head *list, struct list_head *head)
Definition: list.h:203
static void list_splice_tail_init(struct list_head *list, struct list_head *head)
Definition: list.h:222
static void _list_splice(const struct list_head *list, struct list_head *prev, struct list_head *next)
Definition: list.h:185
static void list_move_tail(struct list_head *entry, struct list_head *head)
Definition: list.h:178
static bool list_is_first(const struct list_head *list, const struct list_head *head)
Definition: list.h:75
static void list_add_tail(struct list_head *_new, struct list_head *head)
Definition: list.h:165
static bool list_empty(const struct list_head *head)
Definition: list.h:69
static void list_add(struct list_head *_new, struct list_head *head)
Definition: list.h:159
static void list_splice_init(struct list_head *list, struct list_head *head)
Definition: list.h:215
static void _list_add(struct list_head *_new, struct list_head *prev, struct list_head *next)
Definition: list.h:103
static void list_del(struct list_head *entry)
Definition: list.h:96
static bool list_is_last(const struct list_head *list, const struct list_head *head)
Definition: list.h:82
static void _list_del(struct list_head *entry)
Definition: list.h:89
static void list_del_init(struct list_head *entry)
Definition: list.h:114
static void list_splice_tail(struct list_head *list, struct list_head *head)
Definition: list.h:209
static void INIT_LIST_HEAD(struct list_head *list)
Definition: list.h:63
static void list_move(struct list_head *list, struct list_head *head)
Definition: list.h:171
Definition: list.h:53
struct list_head * next
Definition: list.h:54
struct list_head * prev
Definition: list.h:55