1171095Ssam/*- 2171095Ssam * Copyright (c) 2002-2007 Neterion, Inc. 3171095Ssam * All rights reserved. 4171095Ssam * 5171095Ssam * Redistribution and use in source and binary forms, with or without 6171095Ssam * modification, are permitted provided that the following conditions 7171095Ssam * are met: 8171095Ssam * 1. Redistributions of source code must retain the above copyright 9171095Ssam * notice, this list of conditions and the following disclaimer. 10171095Ssam * 2. Redistributions in binary form must reproduce the above copyright 11171095Ssam * notice, this list of conditions and the following disclaimer in the 12171095Ssam * documentation and/or other materials provided with the distribution. 13171095Ssam * 14171095Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15171095Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16171095Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17171095Ssam * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18171095Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19171095Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20171095Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21171095Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22171095Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23171095Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24171095Ssam * SUCH DAMAGE. 25171095Ssam * 26171095Ssam * $FreeBSD$ 27171095Ssam */ 28171095Ssam 29171095Ssam#ifndef XGE_LIST_H 30171095Ssam#define XGE_LIST_H 31171095Ssam 32171095Ssam#include <dev/nxge/include/xge-debug.h> 33171095Ssam 34171095Ssam__EXTERN_BEGIN_DECLS 35171095Ssam 36171095Ssam/** 37171095Ssam * struct xge_list_t - List item. 38171095Ssam * @prev: Previous list item. 39171095Ssam * @next: Next list item. 40171095Ssam * 41171095Ssam * Item of a bi-directional linked list. 42171095Ssam */ 43171095Ssamtypedef struct xge_list_t { 44171095Ssam struct xge_list_t* prev; 45171095Ssam struct xge_list_t* next; 46171095Ssam} xge_list_t; 47171095Ssam 48171095Ssam/** 49171095Ssam * xge_list_init - Initialize linked list. 50171095Ssam * header: first element of the list (head) 51171095Ssam * 52171095Ssam * Initialize linked list. 53171095Ssam * See also: xge_list_t{}. 54171095Ssam */ 55171095Ssamstatic inline void xge_list_init (xge_list_t *header) 56171095Ssam{ 57171095Ssam header->next = header; 58171095Ssam header->prev = header; 59171095Ssam} 60171095Ssam 61171095Ssam/** 62171095Ssam * xge_list_is_empty - Is the list empty? 63171095Ssam * header: first element of the list (head) 64171095Ssam * 65171095Ssam * Determine whether the bi-directional list is empty. Return '1' in 66171095Ssam * case of 'empty'. 67171095Ssam * See also: xge_list_t{}. 68171095Ssam */ 69171095Ssamstatic inline int xge_list_is_empty(xge_list_t *header) 70171095Ssam{ 71173139Srwatson xge_assert(header != NULL); 72171095Ssam 73173139Srwatson return header->next == header; 74171095Ssam} 75171095Ssam 76171095Ssam/** 77171095Ssam * xge_list_first_get - Return the first item from the linked list. 78171095Ssam * header: first element of the list (head) 79171095Ssam * 80171095Ssam * Returns the next item from the header. 81171095Ssam * Returns NULL if the next item is header itself 82171095Ssam * See also: xge_list_remove(), xge_list_insert(), xge_list_t{}. 83171095Ssam */ 84171095Ssamstatic inline xge_list_t *xge_list_first_get(xge_list_t *header) 85171095Ssam{ 86171095Ssam xge_assert(header != NULL); 87171095Ssam xge_assert(header->next != NULL); 88171095Ssam xge_assert(header->prev != NULL); 89171095Ssam 90171095Ssam if(header->next == header) 91173139Srwatson return NULL; 92171095Ssam else 93173139Srwatson return header->next; 94171095Ssam} 95171095Ssam 96171095Ssam/** 97171095Ssam * xge_list_remove - Remove the specified item from the linked list. 98171095Ssam * item: element of the list 99171095Ssam * 100171095Ssam * Remove item from a list. 101171095Ssam * See also: xge_list_insert(), xge_list_t{}. 102171095Ssam */ 103171095Ssamstatic inline void xge_list_remove(xge_list_t *item) 104171095Ssam{ 105171095Ssam xge_assert(item != NULL); 106171095Ssam xge_assert(item->next != NULL); 107171095Ssam xge_assert(item->prev != NULL); 108171095Ssam 109171095Ssam item->next->prev = item->prev; 110171095Ssam item->prev->next = item->next; 111171095Ssam#ifdef XGE_DEBUG_ASSERT 112171095Ssam item->next = item->prev = NULL; 113171095Ssam#endif 114171095Ssam} 115171095Ssam 116171095Ssam/** 117171095Ssam * xge_list_insert - Insert a new item after the specified item. 118171095Ssam * new_item: new element of the list 119171095Ssam * prev_item: element of the list after which the new element is 120171095Ssam * inserted 121171095Ssam * 122171095Ssam * Insert new item (new_item) after given item (prev_item). 123171095Ssam * See also: xge_list_remove(), xge_list_insert_before(), xge_list_t{}. 124171095Ssam */ 125171095Ssamstatic inline void xge_list_insert (xge_list_t *new_item, 126173139Srwatson xge_list_t *prev_item) 127171095Ssam{ 128171095Ssam xge_assert(new_item != NULL); 129171095Ssam xge_assert(prev_item != NULL); 130171095Ssam xge_assert(prev_item->next != NULL); 131171095Ssam 132171095Ssam new_item->next = prev_item->next; 133171095Ssam new_item->prev = prev_item; 134171095Ssam prev_item->next->prev = new_item; 135171095Ssam prev_item->next = new_item; 136171095Ssam} 137171095Ssam 138171095Ssam/** 139171095Ssam * xge_list_insert_before - Insert a new item before the specified item. 140171095Ssam * new_item: new element of the list 141171095Ssam * next_item: element of the list after which the new element is inserted 142171095Ssam * 143171095Ssam * Insert new item (new_item) before given item (next_item). 144171095Ssam */ 145171095Ssamstatic inline void xge_list_insert_before (xge_list_t *new_item, 146173139Srwatson xge_list_t *next_item) 147171095Ssam{ 148171095Ssam xge_assert(new_item != NULL); 149171095Ssam xge_assert(next_item != NULL); 150171095Ssam xge_assert(next_item->next != NULL); 151171095Ssam 152171095Ssam new_item->next = next_item; 153171095Ssam new_item->prev = next_item->prev; 154171095Ssam next_item->prev->next = new_item; 155171095Ssam next_item->prev = new_item; 156171095Ssam} 157171095Ssam 158171095Ssam#define xge_list_for_each(_p, _h) \ 159171095Ssam for (_p = (_h)->next, xge_os_prefetch(_p->next); _p != (_h); \ 160173139Srwatson _p = _p->next, xge_os_prefetch(_p->next)) 161171095Ssam 162171095Ssam#define xge_list_for_each_safe(_p, _n, _h) \ 163173139Srwatson for (_p = (_h)->next, _n = _p->next; _p != (_h); \ 164173139Srwatson _p = _n, _n = _p->next) 165171095Ssam 166171095Ssam#ifdef __GNUC__ 167171095Ssam/** 168171095Ssam * xge_container_of - Given a member, return the containing structure. 169173139Srwatson * @ptr: the pointer to the member. 170173139Srwatson * @type: the type of the container struct this is embedded in. 171173139Srwatson * @member: the name of the member within the struct. 172171095Ssam * 173171095Ssam * Cast a member of a structure out to the containing structure. 174171095Ssam */ 175173139Srwatson#define xge_container_of(ptr, type, member) ({ \ 176173139Srwatson __typeof( ((type *)0)->member ) *__mptr = (ptr); \ 177173139Srwatson (type *)(void *)( (char *)__mptr - ((size_t) &((type *)0)->member) );}) 178171095Ssam#else 179171095Ssam/* type unsafe version */ 180171095Ssam#define xge_container_of(ptr, type, member) \ 181173139Srwatson ((type*)(void*)((char*)(ptr) - ((size_t) &((type *)0)->member))) 182171095Ssam#endif 183171095Ssam 184171095Ssam/** 185171095Ssam * xge_offsetof - Offset of the member in the containing structure. 186173139Srwatson * @t: struct name. 187173139Srwatson * @m: the name of the member within the struct. 188171095Ssam * 189171095Ssam * Return the offset of the member @m in the structure @t. 190171095Ssam */ 191171095Ssam#define xge_offsetof(t, m) ((size_t) (&((t *)0)->m)) 192171095Ssam 193171095Ssam__EXTERN_END_DECLS 194171095Ssam 195171095Ssam#endif /* XGE_LIST_H */ 196