• 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_prev_entry(pos, member)            list_entry((pos)->member.prev, typeof(*(pos)), member)
125 #define list_entry_is_h(p, h, field)            (&p->field == (h))
126 
127 #define list_for_each(p, head)                                          \
128         for (p = (head)->next; p != (head); p = p->next)
129 
130 #define list_for_each_safe(p, n, head)                                  \
131         for (p = (head)->next, n = p->next; p != (head); p = n, n = p->next)
132 
133 #define list_for_each_entry(p, h, field)                                \
134         for (p = list_first_entry(h, __typeof__(*p), field); &p->field != (h); \
135             p = list_entry(p->field.next, __typeof__(*p), field))
136 
137 #define list_for_each_entry_continue(p, h, field)                       \
138         for (p = list_next_entry(p, field);                             \
139              !list_entry_is_h(p, h, field);                             \
140              p = list_next_entry(p, field))
141 
142 #define list_for_each_entry_continue_reverse(p, h, field)               \
143         for (p = list_prev_entry(p, field);                             \
144              !list_entry_is_h(p, h, field);                             \
145              p = list_prev_entry(p, field))
146 
147 #define list_for_each_entry_safe(p, n, h, field)                        \
148         for (p = list_first_entry(h, __typeof__(*p), field),            \
149             n = list_entry(p->field.next, __typeof__(*p), field); &p->field != (h);\
150             p = n, n = list_entry(n->field.next, __typeof__(*n), field))
151 
152 #define list_for_each_entry_reverse(p, h, field)                        \
153         for (p = list_last_entry(h, __typeof__(*p), field); &p->field != (h); \
154             p = list_entry(p->field.prev, __typeof__(*p), field))
155 
156 #define list_for_each_prev(p, h) for (p = (h)->prev; p != (h); p = p->prev)
157 #define list_for_each_prev_safe(p, n, h) for (p = (h)->prev, n = p->prev; p != (h); p = n, n = p->prev)
158 
159 static inline void
160 list_add(struct list_head *_new, struct list_head *head)
161 {
162         _list_add(_new, head, head->next);
163 }
164 
165 static inline void
166 list_add_tail(struct list_head *_new, struct list_head *head)
167 {
168         _list_add(_new, head->prev, head);
169 }
170 
171 static inline void
172 list_move(struct list_head *list, struct list_head *head)
173 {
174         _list_del(list);
175         list_add(list, head);
176 }
177 
178 static inline void
179 list_move_tail(struct list_head *entry, struct list_head *head)
180 {
181         _list_del(entry);
182         list_add_tail(entry, head);
183 }
184 
185 static inline void
186 _list_splice(const struct list_head *list, struct list_head *prev,
187     struct list_head *next)
188 {
189         struct list_head *first;
190         struct list_head *last;
191 
192         if (list_empty(list))
193                 return;
194 
195         first = list->next;
196         last = list->prev;
197         first->prev = prev;
198         prev->next = first;
199         last->next = next;
200         next->prev = last;
201 }
202 
203 static inline void
204 list_splice(const struct list_head *list, struct list_head *head)
205 {
206         _list_splice(list, head, head->next);
207 }
208 
209 static inline void
210 list_splice_tail(struct list_head *list, struct list_head *head)
211 {
212         _list_splice(list, head->prev, head);
213 }
214 
215 static inline void
216 list_splice_init(struct list_head *list, struct list_head *head)
217 {
218         _list_splice(list, head, head->next);
219         INIT_LIST_HEAD(list);
220 }
221 
222 static inline void
223 list_splice_tail_init(struct list_head *list, struct list_head *head)
224 {
225         _list_splice(list, head->prev, head);
226         INIT_LIST_HEAD(list);
227 }
228 
229 #endif /* _LINUX_LIST_H_ */
230 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt