1/*- 2 * Copyright (c) 2002-2007 Neterion, Inc. 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 AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29#ifndef XGE_LIST_H 30#define XGE_LIST_H 31 32#include <dev/nxge/include/xge-debug.h> 33 34__EXTERN_BEGIN_DECLS 35 36/** 37 * struct xge_list_t - List item. 38 * @prev: Previous list item. 39 * @next: Next list item. 40 * 41 * Item of a bi-directional linked list. 42 */ 43typedef struct xge_list_t { 44 struct xge_list_t* prev; 45 struct xge_list_t* next; 46} xge_list_t; 47 48/** 49 * xge_list_init - Initialize linked list. 50 * header: first element of the list (head) 51 * 52 * Initialize linked list. 53 * See also: xge_list_t{}. 54 */ 55static inline void xge_list_init (xge_list_t *header) 56{ 57 header->next = header; 58 header->prev = header; 59} 60 61/** 62 * xge_list_is_empty - Is the list empty? 63 * header: first element of the list (head) 64 * 65 * Determine whether the bi-directional list is empty. Return '1' in 66 * case of 'empty'. 67 * See also: xge_list_t{}. 68 */ 69static inline int xge_list_is_empty(xge_list_t *header) 70{ 71 xge_assert(header != NULL); 72 73 return header->next == header; 74} 75 76/** 77 * xge_list_first_get - Return the first item from the linked list. 78 * header: first element of the list (head) 79 * 80 * Returns the next item from the header. 81 * Returns NULL if the next item is header itself 82 * See also: xge_list_remove(), xge_list_insert(), xge_list_t{}. 83 */ 84static inline xge_list_t *xge_list_first_get(xge_list_t *header) 85{ 86 xge_assert(header != NULL); 87 xge_assert(header->next != NULL); 88 xge_assert(header->prev != NULL); 89 90 if(header->next == header) 91 return NULL; 92 else 93 return header->next; 94} 95 96/** 97 * xge_list_remove - Remove the specified item from the linked list. 98 * item: element of the list 99 * 100 * Remove item from a list. 101 * See also: xge_list_insert(), xge_list_t{}. 102 */ 103static inline void xge_list_remove(xge_list_t *item) 104{ 105 xge_assert(item != NULL); 106 xge_assert(item->next != NULL); 107 xge_assert(item->prev != NULL); 108 109 item->next->prev = item->prev; 110 item->prev->next = item->next; 111#ifdef XGE_DEBUG_ASSERT 112 item->next = item->prev = NULL; 113#endif 114} 115 116/** 117 * xge_list_insert - Insert a new item after the specified item. 118 * new_item: new element of the list 119 * prev_item: element of the list after which the new element is 120 * inserted 121 * 122 * Insert new item (new_item) after given item (prev_item). 123 * See also: xge_list_remove(), xge_list_insert_before(), xge_list_t{}. 124 */ 125static inline void xge_list_insert (xge_list_t *new_item, 126 xge_list_t *prev_item) 127{ 128 xge_assert(new_item != NULL); 129 xge_assert(prev_item != NULL); 130 xge_assert(prev_item->next != NULL); 131 132 new_item->next = prev_item->next; 133 new_item->prev = prev_item; 134 prev_item->next->prev = new_item; 135 prev_item->next = new_item; 136} 137 138/** 139 * xge_list_insert_before - Insert a new item before the specified item. 140 * new_item: new element of the list 141 * next_item: element of the list after which the new element is inserted 142 * 143 * Insert new item (new_item) before given item (next_item). 144 */ 145static inline void xge_list_insert_before (xge_list_t *new_item, 146 xge_list_t *next_item) 147{ 148 xge_assert(new_item != NULL); 149 xge_assert(next_item != NULL); 150 xge_assert(next_item->next != NULL); 151 152 new_item->next = next_item; 153 new_item->prev = next_item->prev; 154 next_item->prev->next = new_item; 155 next_item->prev = new_item; 156} 157 158#define xge_list_for_each(_p, _h) \ 159 for (_p = (_h)->next, xge_os_prefetch(_p->next); _p != (_h); \ 160 _p = _p->next, xge_os_prefetch(_p->next)) 161 162#define xge_list_for_each_safe(_p, _n, _h) \ 163 for (_p = (_h)->next, _n = _p->next; _p != (_h); \ 164 _p = _n, _n = _p->next) 165 166#ifdef __GNUC__ 167/** 168 * xge_container_of - Given a member, return the containing structure. 169 * @ptr: the pointer to the member. 170 * @type: the type of the container struct this is embedded in. 171 * @member: the name of the member within the struct. 172 * 173 * Cast a member of a structure out to the containing structure. 174 */ 175#define xge_container_of(ptr, type, member) ({ \ 176 __typeof( ((type *)0)->member ) *__mptr = (ptr); \ 177 (type *)(void *)( (char *)__mptr - ((size_t) &((type *)0)->member) );}) 178#else 179/* type unsafe version */ 180#define xge_container_of(ptr, type, member) \ 181 ((type*)(void*)((char*)(ptr) - ((size_t) &((type *)0)->member))) 182#endif 183 184/** 185 * xge_offsetof - Offset of the member in the containing structure. 186 * @t: struct name. 187 * @m: the name of the member within the struct. 188 * 189 * Return the offset of the member @m in the structure @t. 190 */ 191#define xge_offsetof(t, m) ((size_t) (&((t *)0)->m)) 192 193__EXTERN_END_DECLS 194 195#endif /* XGE_LIST_H */ 196