|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2009, 2010 Richard Braun. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms, with or without ! 6: * modification, are permitted provided that the following conditions ! 7: * are met: ! 8: * 1. Redistributions of source code must retain the above copyright ! 9: * notice, this list of conditions and the following disclaimer. ! 10: * 2. Redistributions in binary form must reproduce the above copyright ! 11: * notice, this list of conditions and the following disclaimer in the ! 12: * documentation and/or other materials provided with the distribution. ! 13: * ! 14: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ! 15: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ! 16: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ! 17: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ! 18: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ! 19: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ! 20: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ! 21: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ! 22: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ! 23: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ! 24: * ! 25: * ! 26: * Simple doubly-linked list. ! 27: */ ! 28: ! 29: #ifndef _KERN_LIST_H ! 30: #define _KERN_LIST_H ! 31: ! 32: #include <stddef.h> ! 33: #include <sys/types.h> ! 34: ! 35: #define structof(ptr, type, member) \ ! 36: ((type *)((char *)ptr - offsetof(type, member))) ! 37: ! 38: /* ! 39: * Structure used as both head and node. ! 40: * ! 41: * This implementation relies on using the same type for both heads and nodes. ! 42: * ! 43: * It is recommended to encode the use of struct list variables in their names, ! 44: * e.g. struct list free_list or struct list free_objects is a good hint for a ! 45: * list of free objects. A declaration like struct list free_node clearly ! 46: * indicates it is used as part of a node in the free list. ! 47: */ ! 48: struct list { ! 49: struct list *prev; ! 50: struct list *next; ! 51: }; ! 52: ! 53: /* ! 54: * Static list initializer. ! 55: */ ! 56: #define LIST_INITIALIZER(list) { &(list), &(list) } ! 57: ! 58: /* ! 59: * Initialize a list. ! 60: */ ! 61: static inline void list_init(struct list *list) ! 62: { ! 63: list->prev = list; ! 64: list->next = list; ! 65: } ! 66: ! 67: /* ! 68: * Initialize a list node. ! 69: * ! 70: * An entry is in no list when its node members point to NULL. ! 71: */ ! 72: static inline void list_node_init(struct list *node) ! 73: { ! 74: node->prev = NULL; ! 75: node->next = NULL; ! 76: } ! 77: ! 78: /* ! 79: * Return true if node is in no list. ! 80: */ ! 81: static inline int list_node_unlinked(const struct list *node) ! 82: { ! 83: return node->prev == NULL; ! 84: } ! 85: ! 86: /* ! 87: * Macro that evaluates to the address of the structure containing the ! 88: * given node based on the given type and member. ! 89: */ ! 90: #define list_entry(node, type, member) structof(node, type, member) ! 91: ! 92: /* ! 93: * Return the first node of a list. ! 94: */ ! 95: static inline struct list * list_first(const struct list *list) ! 96: { ! 97: return list->next; ! 98: } ! 99: ! 100: /* ! 101: * Return the last node of a list. ! 102: */ ! 103: static inline struct list * list_last(const struct list *list) ! 104: { ! 105: return list->prev; ! 106: } ! 107: ! 108: /* ! 109: * Return the node next to the given node. ! 110: */ ! 111: static inline struct list * list_next(const struct list *node) ! 112: { ! 113: return node->next; ! 114: } ! 115: ! 116: /* ! 117: * Return the node previous to the given node. ! 118: */ ! 119: static inline struct list * list_prev(const struct list *node) ! 120: { ! 121: return node->prev; ! 122: } ! 123: ! 124: /* ! 125: * Get the first entry of a list. ! 126: */ ! 127: #define list_first_entry(list, type, member) \ ! 128: list_entry(list_first(list), type, member) ! 129: ! 130: /* ! 131: * Get the last entry of a list. ! 132: */ ! 133: #define list_last_entry(list, type, member) \ ! 134: list_entry(list_last(list), type, member) ! 135: ! 136: /* ! 137: * Return true if node is after the last or before the first node of the list. ! 138: */ ! 139: static inline int list_end(const struct list *list, const struct list *node) ! 140: { ! 141: return list == node; ! 142: } ! 143: ! 144: /* ! 145: * Return true if list is empty. ! 146: */ ! 147: static inline int list_empty(const struct list *list) ! 148: { ! 149: return list == list->next; ! 150: } ! 151: ! 152: /* ! 153: * Return true if list contains exactly one node. ! 154: */ ! 155: static inline int list_singular(const struct list *list) ! 156: { ! 157: return (list != list->next) && (list->next == list->prev); ! 158: } ! 159: ! 160: /* ! 161: * Split list2 by moving its nodes up to (but not including) the given ! 162: * node into list1 (which can be in a stale state). ! 163: * ! 164: * If list2 is empty, or node is list2 or list2->next, nothing is done. ! 165: */ ! 166: static inline void list_split(struct list *list1, struct list *list2, ! 167: struct list *node) ! 168: { ! 169: if (list_empty(list2) || (list2->next == node) || list_end(list2, node)) ! 170: return; ! 171: ! 172: list1->next = list2->next; ! 173: list1->next->prev = list1; ! 174: ! 175: list1->prev = node->prev; ! 176: node->prev->next = list1; ! 177: ! 178: list2->next = node; ! 179: node->prev = list2; ! 180: } ! 181: ! 182: /* ! 183: * Append the nodes of list2 at the end of list1. ! 184: * ! 185: * After completion, list2 is stale. ! 186: */ ! 187: static inline void list_concat(struct list *list1, const struct list *list2) ! 188: { ! 189: struct list *last1, *first2, *last2; ! 190: ! 191: if (list_empty(list2)) ! 192: return; ! 193: ! 194: last1 = list1->prev; ! 195: first2 = list2->next; ! 196: last2 = list2->prev; ! 197: ! 198: last1->next = first2; ! 199: first2->prev = last1; ! 200: ! 201: last2->next = list1; ! 202: list1->prev = last2; ! 203: } ! 204: ! 205: /* ! 206: * Set the new head of a list. ! 207: * ! 208: * This function is an optimized version of : ! 209: * list_init(&new_list); ! 210: * list_concat(&new_list, &old_list); ! 211: * ! 212: * After completion, old_head is stale. ! 213: */ ! 214: static inline void list_set_head(struct list *new_head, ! 215: const struct list *old_head) ! 216: { ! 217: if (list_empty(old_head)) { ! 218: list_init(new_head); ! 219: return; ! 220: } ! 221: ! 222: *new_head = *old_head; ! 223: new_head->next->prev = new_head; ! 224: new_head->prev->next = new_head; ! 225: } ! 226: ! 227: /* ! 228: * Add a node between two nodes. ! 229: */ ! 230: static inline void list_add(struct list *prev, struct list *next, ! 231: struct list *node) ! 232: { ! 233: next->prev = node; ! 234: node->next = next; ! 235: ! 236: prev->next = node; ! 237: node->prev = prev; ! 238: } ! 239: ! 240: /* ! 241: * Insert a node at the head of a list. ! 242: */ ! 243: static inline void list_insert_head(struct list *list, struct list *node) ! 244: { ! 245: list_add(list, list->next, node); ! 246: } ! 247: ! 248: /* ! 249: * Insert a node at the tail of a list. ! 250: */ ! 251: static inline void list_insert_tail(struct list *list, struct list *node) ! 252: { ! 253: list_add(list->prev, list, node); ! 254: } ! 255: ! 256: /* ! 257: * Insert a node before another node. ! 258: */ ! 259: static inline void list_insert_before(struct list *next, struct list *node) ! 260: { ! 261: list_add(next->prev, next, node); ! 262: } ! 263: ! 264: /* ! 265: * Insert a node after another node. ! 266: */ ! 267: static inline void list_insert_after(struct list *prev, struct list *node) ! 268: { ! 269: list_add(prev, prev->next, node); ! 270: } ! 271: ! 272: /* ! 273: * Remove a node from a list. ! 274: * ! 275: * After completion, the node is stale. ! 276: */ ! 277: static inline void list_remove(struct list *node) ! 278: { ! 279: node->prev->next = node->next; ! 280: node->next->prev = node->prev; ! 281: } ! 282: ! 283: /* ! 284: * Forge a loop to process all nodes of a list. ! 285: * ! 286: * The node must not be altered during the loop. ! 287: */ ! 288: #define list_for_each(list, node) \ ! 289: for (node = list_first(list); \ ! 290: !list_end(list, node); \ ! 291: node = list_next(node)) ! 292: ! 293: /* ! 294: * Forge a loop to process all nodes of a list. ! 295: */ ! 296: #define list_for_each_safe(list, node, tmp) \ ! 297: for (node = list_first(list), tmp = list_next(node); \ ! 298: !list_end(list, node); \ ! 299: node = tmp, tmp = list_next(node)) ! 300: ! 301: /* ! 302: * Version of list_for_each() that processes nodes backward. ! 303: */ ! 304: #define list_for_each_reverse(list, node) \ ! 305: for (node = list_last(list); \ ! 306: !list_end(list, node); \ ! 307: node = list_prev(node)) ! 308: ! 309: /* ! 310: * Version of list_for_each_safe() that processes nodes backward. ! 311: */ ! 312: #define list_for_each_reverse_safe(list, node, tmp) \ ! 313: for (node = list_last(list), tmp = list_prev(node); \ ! 314: !list_end(list, node); \ ! 315: node = tmp, tmp = list_prev(node)) ! 316: ! 317: /* ! 318: * Forge a loop to process all entries of a list. ! 319: * ! 320: * The entry node must not be altered during the loop. ! 321: */ ! 322: #define list_for_each_entry(list, entry, member) \ ! 323: for (entry = list_entry(list_first(list), typeof(*entry), member); \ ! 324: !list_end(list, &entry->member); \ ! 325: entry = list_entry(list_next(&entry->member), typeof(*entry), \ ! 326: member)) ! 327: ! 328: /* ! 329: * Forge a loop to process all entries of a list. ! 330: */ ! 331: #define list_for_each_entry_safe(list, entry, tmp, member) \ ! 332: for (entry = list_entry(list_first(list), typeof(*entry), member), \ ! 333: tmp = list_entry(list_next(&entry->member), typeof(*entry), \ ! 334: member); \ ! 335: !list_end(list, &entry->member); \ ! 336: entry = tmp, tmp = list_entry(list_next(&entry->member), \ ! 337: typeof(*entry), member)) ! 338: ! 339: /* ! 340: * Version of list_for_each_entry() that processes entries backward. ! 341: */ ! 342: #define list_for_each_entry_reverse(list, entry, member) \ ! 343: for (entry = list_entry(list_last(list), typeof(*entry), member); \ ! 344: !list_end(list, &entry->member); \ ! 345: entry = list_entry(list_prev(&entry->member), typeof(*entry), \ ! 346: member)) ! 347: ! 348: /* ! 349: * Version of list_for_each_entry_safe() that processes entries backward. ! 350: */ ! 351: #define list_for_each_entry_reverse_safe(list, entry, tmp, member) \ ! 352: for (entry = list_entry(list_last(list), typeof(*entry), member), \ ! 353: tmp = list_entry(list_prev(&entry->member), typeof(*entry), \ ! 354: member); \ ! 355: !list_end(list, &entry->member); \ ! 356: entry = tmp, tmp = list_entry(list_prev(&entry->member), \ ! 357: typeof(*entry), member)) ! 358: ! 359: #endif /* _KERN_LIST_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.