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 22 /* 23 * Copyright (c) 2002-2005 Neterion, Inc. 24 * All right Reserved. 25 * 26 * FileName : xge-list.h 27 * 28 * Description: Generic bi-directional linked list implementation 29 * 30 * Created: 14 May 2004 31 */ 32 33 #ifndef XGE_LIST_H 34 #define XGE_LIST_H 35 36 #include "xge-debug.h" 37 38 /** 39 * struct xge_list_t - List item. 40 * @prev: Previous list item. 41 * @next: Next list item. 42 * 43 * Item of a bi-directional linked list. 44 */ 45 typedef struct xge_list_t { 46 struct xge_list_t* prev; 47 struct xge_list_t* next; 48 } xge_list_t; 49 50 /** 51 * xge_list_init - Initialize linked list. 52 * header: first element of the list (head) 53 * 54 * Initialize linked list. 55 * See also: xge_list_t{}. 56 */ 57 static inline void xge_list_init (xge_list_t *header) 58 { 59 header->next = header; 60 header->prev = header; 61 } 62 63 /** 64 * xge_list_is_empty - Is the list empty? 65 * header: first element of the list (head) 66 * 67 * Determine whether the bi-directional list is empty. Return '1' in 68 * case of 'empty'. 69 * See also: xge_list_t{}. 70 */ 71 static inline int xge_list_is_empty(xge_list_t *header) 72 { 73 xge_assert(header != NULL); 74 75 return header->next == header; 76 } 77 78 /** 79 * xge_list_remove - Remove the specified item from the linked list. 80 * item: element of the list 81 * 82 * Remove item from a list. 83 * See also: xge_list_insert(), xge_list_t{}. 84 */ 85 static inline void xge_list_remove(xge_list_t *item) 86 { 87 xge_assert(item != NULL); 88 xge_assert(item->next != NULL); 89 xge_assert(item->prev != NULL); 90 91 item->next->prev = item->prev; 92 item->prev->next = item->next; 93 #ifdef XGE_DEBUG_ASSERT 94 item->next = item->prev = NULL; 95 #endif 96 } 97 98 /** 99 * xge_list_insert - Insert a new item after the specified item. 100 * new_item: new element of the list 101 * prev_item: element of the list after which the new element is 102 * inserted 103 * 104 * Insert new item (new_item) after given item (prev_item). 105 * See also: xge_list_remove(), xge_list_insert_before(), xge_list_t{}. 106 */ 107 static inline void xge_list_insert (xge_list_t *new_item, 108 xge_list_t *prev_item) 109 { 110 xge_assert(new_item != NULL); 111 xge_assert(prev_item != NULL); 112 xge_assert(prev_item->next != NULL); 113 114 new_item->next = prev_item->next; 115 new_item->prev = prev_item; 116 prev_item->next->prev = new_item; 117 prev_item->next = new_item; 118 } 119 120 /** 121 * xge_list_insert_before - Insert a new item before the specified item. 122 * new_item: new element of the list 123 * next_item: element of the list after which the new element is inserted 124 * 125 * Insert new item (new_item) before given item (next_item). 126 */ 127 static inline void xge_list_insert_before (xge_list_t *new_item, 128 xge_list_t *next_item) 129 { 130 xge_assert(new_item != NULL); 131 xge_assert(next_item != NULL); 132 xge_assert(next_item->next != NULL); 133 134 new_item->next = next_item; 135 new_item->prev = next_item->prev; 136 next_item->prev->next = new_item; 137 next_item->prev = new_item; 138 } 139 140 #define xge_list_for_each(_p, _h) \ 141 for (_p = (_h)->next, xge_os_prefetch(_p->next); _p != (_h); \ 142 _p = _p->next, xge_os_prefetch(_p->next)) 143 144 #define xge_list_for_each_safe(_p, _n, _h) \ 145 for (_p = (_h)->next, _n = _p->next; _p != (_h); \ 146 _p = _n, _n = _p->next) 147 148 #ifdef __GNUC__ 149 /** 150 * xge_container_of - Given a member, return the containing structure. 151 * @ptr: the pointer to the member. 152 * @type: the type of the container struct this is embedded in. 153 * @member: the name of the member within the struct. 154 * 155 * Cast a member of a structure out to the containing structure. 156 */ 157 #define xge_container_of(ptr, type, member) ({ \ 158 const __typeof( ((type *)0)->member ) *__mptr = (ptr); \ 159 (type *)(void *)( (char *)__mptr - ((size_t) &((type *)0)->member) );}) 160 #else 161 /* type unsafe version */ 162 #define xge_container_of(ptr, type, member) \ 163 ((type*)(void*)((char*)(ptr) - ((size_t) &((type *)0)->member))) 164 #endif 165 166 /** 167 * xge_offsetof - Offset of the member in the containing structure. 168 * @t: struct name. 169 * @m: the name of the member within the struct. 170 * 171 * Return the offset of the member @m in the structure @t. 172 */ 173 #define xge_offsetof(t, m) ((size_t) (&((t *)0)->m)) 174 175 #endif /* XGE_LIST_H */ 176