• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/libubox/list.h

  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
 63 INIT_LIST_HEAD(struct list_head *list)
 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_ */
229 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt