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