1/* 2 * Copyright © 2010 Intel Corporation 3 * Copyright © 2010 Francisco Jerez <currojerez@riseup.net> 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 * IN THE SOFTWARE. 23 * 24 */ 25 26#ifndef _LIST_H_ 27#define _LIST_H_ 28 29/* classic doubly-link circular list */ 30struct list { 31 struct list *next, *prev; 32}; 33 34static void 35list_init(struct list *list) 36{ 37 list->next = list->prev = list; 38} 39 40static inline void 41__list_add(struct list *entry, 42 struct list *prev, 43 struct list *next) 44{ 45 next->prev = entry; 46 entry->next = next; 47 entry->prev = prev; 48 prev->next = entry; 49} 50 51static inline void 52list_add(struct list *entry, struct list *head) 53{ 54 __list_add(entry, head, head->next); 55} 56 57static inline void 58__list_del(struct list *prev, struct list *next) 59{ 60 next->prev = prev; 61 prev->next = next; 62} 63 64static inline void 65list_del(struct list *entry) 66{ 67 __list_del(entry->prev, entry->next); 68 list_init(entry); 69} 70 71static inline Bool 72list_is_empty(const struct list *head) 73{ 74 return head->next == head; 75} 76 77#ifndef container_of 78#define container_of(ptr, type, member) \ 79 (type *)((char *)(ptr) - (char *) &((type *)0)->member) 80#endif 81 82#define list_entry(ptr, type, member) \ 83 container_of(ptr, type, member) 84 85#define list_first_entry(ptr, type, member) \ 86 list_entry((ptr)->next, type, member) 87 88#define __container_of(ptr, sample, member) \ 89 (void *)((char *)(ptr) \ 90 - ((char *)&(sample)->member - (char *)(sample))) 91 92#define list_for_each_entry(pos, head, member) \ 93 for (pos = __container_of((head)->next, pos, member); \ 94 &pos->member != (head); \ 95 pos = __container_of(pos->member.next, pos, member)) 96 97#define list_for_each_entry_safe(pos, tmp, head, member) \ 98 for (pos = __container_of((head)->next, pos, member), \ 99 tmp = __container_of(pos->member.next, pos, member); \ 100 &pos->member != (head); \ 101 pos = tmp, tmp = __container_of(pos->member.next, tmp, member)) 102 103static inline void 104list_append(struct list *entry, struct list *head) 105{ 106 __list_add(entry, head, head->next); 107} 108 109#endif 110