1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 * 21 * Copyright (c) 2002-2006 Neterion, Inc. 22 */ 23 24 #ifndef XGE_LIST_H 25 #define XGE_LIST_H 26 27 #include "xge-debug.h" 28 29 __EXTERN_BEGIN_DECLS 30 31 /** 32 * struct xge_list_t - List item. 33 * @prev: Previous list item. 34 * @next: Next list item. 35 * 36 * Item of a bi-directional linked list. 37 */ 38 typedef struct xge_list_t { 39 struct xge_list_t* prev; 40 struct xge_list_t* next; 41 } xge_list_t; 42 43 /** 44 * xge_list_init - Initialize linked list. 45 * header: first element of the list (head) 46 * 47 * Initialize linked list. 48 * See also: xge_list_t{}. 49 */ 50 static inline void xge_list_init (xge_list_t *header) 51 { 52 header->next = header; 53 header->prev = header; 54 } 55 56 /** 57 * xge_list_is_empty - Is the list empty? 58 * header: first element of the list (head) 59 * 60 * Determine whether the bi-directional list is empty. Return '1' in 61 * case of 'empty'. 62 * See also: xge_list_t{}. 63 */ 64 static inline int xge_list_is_empty(xge_list_t *header) 65 { 66 xge_assert(header != NULL); 67 68 return header->next == header; 69 } 70 71 /** 72 * xge_list_first_get - Return the first item from the linked list. 73 * header: first element of the list (head) 74 * 75 * Returns the next item from the header. 76 * Returns NULL if the next item is header itself 77 * See also: xge_list_remove(), xge_list_insert(), xge_list_t{}. 78 */ 79 static inline xge_list_t *xge_list_first_get(xge_list_t *header) 80 { 81 xge_assert(header != NULL); 82 xge_assert(header->next != NULL); 83 xge_assert(header->prev != NULL); 84 85 if(header->next == header) 86 return NULL; 87 else 88 return header->next; 89 } 90 91 /** 92 * xge_list_remove - Remove the specified item from the linked list. 93 * item: element of the list 94 * 95 * Remove item from a list. 96 * See also: xge_list_insert(), xge_list_t{}. 97 */ 98 static inline void xge_list_remove(xge_list_t *item) 99 { 100 xge_assert(item != NULL); 101 xge_assert(item->next != NULL); 102 xge_assert(item->prev != NULL); 103 104 item->next->prev = item->prev; 105 item->prev->next = item->next; 106 #ifdef XGE_DEBUG_ASSERT 107 item->next = item->prev = NULL; 108 #endif 109 } 110 111 /** 112 * xge_list_insert - Insert a new item after the specified item. 113 * new_item: new element of the list 114 * prev_item: element of the list after which the new element is 115 * inserted 116 * 117 * Insert new item (new_item) after given item (prev_item). 118 * See also: xge_list_remove(), xge_list_insert_before(), xge_list_t{}. 119 */ 120 static inline void xge_list_insert (xge_list_t *new_item, 121 xge_list_t *prev_item) 122 { 123 xge_assert(new_item != NULL); 124 xge_assert(prev_item != NULL); 125 xge_assert(prev_item->next != NULL); 126 127 new_item->next = prev_item->next; 128 new_item->prev = prev_item; 129 prev_item->next->prev = new_item; 130 prev_item->next = new_item; 131 } 132 133 /** 134 * xge_list_insert_before - Insert a new item before the specified item. 135 * new_item: new element of the list 136 * next_item: element of the list after which the new element is inserted 137 * 138 * Insert new item (new_item) before given item (next_item). 139 */ 140 static inline void xge_list_insert_before (xge_list_t *new_item, 141 xge_list_t *next_item) 142 { 143 xge_assert(new_item != NULL); 144 xge_assert(next_item != NULL); 145 xge_assert(next_item->next != NULL); 146 147 new_item->next = next_item; 148 new_item->prev = next_item->prev; 149 next_item->prev->next = new_item; 150 next_item->prev = new_item; 151 } 152 153 #define xge_list_for_each(_p, _h) \ 154 for (_p = (_h)->next, xge_os_prefetch(_p->next); _p != (_h); \ 155 _p = _p->next, xge_os_prefetch(_p->next)) 156 157 #define xge_list_for_each_safe(_p, _n, _h) \ 158 for (_p = (_h)->next, _n = _p->next; _p != (_h); \ 159 _p = _n, _n = _p->next) 160 161 #ifdef __GNUC__ 162 /** 163 * xge_container_of - Given a member, return the containing structure. 164 * @ptr: the pointer to the member. 165 * @type: the type of the container struct this is embedded in. 166 * @member: the name of the member within the struct. 167 * 168 * Cast a member of a structure out to the containing structure. 169 */ 170 #define xge_container_of(ptr, type, member) ({ \ 171 __typeof( ((type *)0)->member ) *__mptr = (ptr); \ 172 (type *)(void *)( (char *)__mptr - ((size_t) &((type *)0)->member) );}) 173 #else 174 /* type unsafe version */ 175 #define xge_container_of(ptr, type, member) \ 176 ((type*)(void*)((char*)(ptr) - ((size_t) &((type *)0)->member))) 177 #endif 178 179 /** 180 * xge_offsetof - Offset of the member in the containing structure. 181 * @t: struct name. 182 * @m: the name of the member within the struct. 183 * 184 * Return the offset of the member @m in the structure @t. 185 */ 186 #define xge_offsetof(t, m) ((size_t) (&((t *)0)->m)) 187 188 __EXTERN_END_DECLS 189 190 #endif /* XGE_LIST_H */ 191