1221167Sgnn/*- 2221167Sgnn * Copyright(c) 2002-2011 Exar Corp. 3221167Sgnn * All rights reserved. 4221167Sgnn * 5221167Sgnn * Redistribution and use in source and binary forms, with or without 6221167Sgnn * modification are permitted provided the following conditions are met: 7221167Sgnn * 8221167Sgnn * 1. Redistributions of source code must retain the above copyright notice, 9221167Sgnn * this list of conditions and the following disclaimer. 10221167Sgnn * 11221167Sgnn * 2. Redistributions in binary form must reproduce the above copyright 12221167Sgnn * notice, this list of conditions and the following disclaimer in the 13221167Sgnn * documentation and/or other materials provided with the distribution. 14221167Sgnn * 15221167Sgnn * 3. Neither the name of the Exar Corporation nor the names of its 16221167Sgnn * contributors may be used to endorse or promote products derived from 17221167Sgnn * this software without specific prior written permission. 18221167Sgnn * 19221167Sgnn * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20221167Sgnn * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21221167Sgnn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22221167Sgnn * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23221167Sgnn * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24221167Sgnn * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25221167Sgnn * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26221167Sgnn * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27221167Sgnn * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28221167Sgnn * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29221167Sgnn * POSSIBILITY OF SUCH DAMAGE. 30221167Sgnn */ 31221167Sgnn/*$FreeBSD$*/ 32221167Sgnn 33221167Sgnn#ifndef VXGE_LIST_H 34221167Sgnn#define VXGE_LIST_H 35221167Sgnn 36221167Sgnn__EXTERN_BEGIN_DECLS 37221167Sgnn 38221167Sgnn/* 39221167Sgnn * struct vxge_list_t - List item. 40221167Sgnn * @prev: Previous list item. 41221167Sgnn * @next: Next list item. 42221167Sgnn * 43221167Sgnn * Item of a bi-directional linked list. 44221167Sgnn */ 45221167Sgnntypedef struct vxge_list_t { 46221167Sgnn struct vxge_list_t *prev; 47221167Sgnn struct vxge_list_t *next; 48221167Sgnn} vxge_list_t; 49221167Sgnn 50221167Sgnn/* 51221167Sgnn * vxge_list_init - Initialize linked list. 52221167Sgnn * @header: first element of the list (head) 53221167Sgnn * 54221167Sgnn * Initialize linked list. 55221167Sgnn * See also: vxge_list_t {}. 56221167Sgnn */ 57221167Sgnnstatic inline void vxge_list_init(vxge_list_t *header) 58221167Sgnn{ 59221167Sgnn vxge_assert(header != NULL); 60221167Sgnn 61221167Sgnn header->next = header; 62221167Sgnn header->prev = header; 63221167Sgnn} 64221167Sgnn 65221167Sgnn/* 66221167Sgnn * vxge_list_is_empty - Is the list empty? 67221167Sgnn * @header: first element of the list (head) 68221167Sgnn * 69221167Sgnn * Determine whether the bi-directional list is empty. Return '1' in 70221167Sgnn * case of 'empty'. 71221167Sgnn * See also: vxge_list_t {}. 72221167Sgnn */ 73221167Sgnnstatic inline int vxge_list_is_empty(vxge_list_t *header) 74221167Sgnn{ 75221167Sgnn vxge_assert(header != NULL); 76221167Sgnn 77221167Sgnn return (header->next == header); 78221167Sgnn} 79221167Sgnn 80221167Sgnn/* 81221167Sgnn * vxge_list_first_get - Return the first item from the linked list. 82221167Sgnn * @header: first element of the list (head) 83221167Sgnn * 84221167Sgnn * Returns the next item from the header. 85221167Sgnn * Returns NULL if the next item is header itself 86221167Sgnn * See also: vxge_list_remove(), vxge_list_insert(), vxge_list_t {}. 87221167Sgnn */ 88221167Sgnnstatic inline vxge_list_t *vxge_list_first_get(vxge_list_t *header) 89221167Sgnn{ 90221167Sgnn vxge_assert(header != NULL); 91221167Sgnn vxge_assert(header->next != NULL); 92221167Sgnn vxge_assert(header->prev != NULL); 93221167Sgnn 94221167Sgnn if (header->next == header) 95221167Sgnn return (NULL); 96221167Sgnn else 97221167Sgnn return (header->next); 98221167Sgnn} 99221167Sgnn 100221167Sgnn/* 101221167Sgnn * vxge_list_remove - Remove the specified item from the linked list. 102221167Sgnn * @item: element of the list 103221167Sgnn * 104221167Sgnn * Remove item from a list. 105221167Sgnn * See also: vxge_list_insert(), vxge_list_t {}. 106221167Sgnn */ 107221167Sgnnstatic inline void vxge_list_remove(vxge_list_t *item) 108221167Sgnn{ 109221167Sgnn vxge_assert(item != NULL); 110221167Sgnn vxge_assert(item->next != NULL); 111221167Sgnn vxge_assert(item->prev != NULL); 112221167Sgnn 113221167Sgnn item->next->prev = item->prev; 114221167Sgnn item->prev->next = item->next; 115221167Sgnn#if defined(VXGE_DEBUG_ASSERT) 116221167Sgnn item->next = item->prev = NULL; 117221167Sgnn#endif 118221167Sgnn} 119221167Sgnn 120221167Sgnn/* 121221167Sgnn * vxge_list_insert - Insert a new item after the specified item. 122221167Sgnn * @new_item: new element of the list 123221167Sgnn * @prev_item: element of the list after which the new element is 124221167Sgnn * inserted 125221167Sgnn * 126221167Sgnn * Insert new item (new_item) after given item (prev_item). 127221167Sgnn * See also: vxge_list_remove(), vxge_list_insert_before(), vxge_list_t {}. 128221167Sgnn */ 129221167Sgnnstatic inline void vxge_list_insert(vxge_list_t *new_item, 130221167Sgnn vxge_list_t *prev_item) 131221167Sgnn{ 132221167Sgnn vxge_assert(new_item != NULL); 133221167Sgnn vxge_assert(prev_item != NULL); 134221167Sgnn vxge_assert(prev_item->next != NULL); 135221167Sgnn 136221167Sgnn new_item->next = prev_item->next; 137221167Sgnn new_item->prev = prev_item; 138221167Sgnn prev_item->next->prev = new_item; 139221167Sgnn prev_item->next = new_item; 140221167Sgnn} 141221167Sgnn 142221167Sgnn/* 143221167Sgnn * vxge_list_insert_before - Insert a new item before the specified item. 144221167Sgnn * @new_item: new element of the list 145221167Sgnn * @next_item: element of the list after which the new element is inserted 146221167Sgnn * 147221167Sgnn * Insert new item (new_item) before given item (next_item). 148221167Sgnn */ 149221167Sgnnstatic inline void vxge_list_insert_before(vxge_list_t *new_item, 150221167Sgnn vxge_list_t * next_item) 151221167Sgnn{ 152221167Sgnn vxge_assert(new_item != NULL); 153221167Sgnn vxge_assert(next_item != NULL); 154221167Sgnn vxge_assert(next_item->next != NULL); 155221167Sgnn 156221167Sgnn new_item->next = next_item; 157221167Sgnn new_item->prev = next_item->prev; 158221167Sgnn next_item->prev->next = new_item; 159221167Sgnn next_item->prev = new_item; 160221167Sgnn} 161221167Sgnn 162221167Sgnn#define vxge_list_for_each(_p, _h) \ 163221167Sgnn for (_p = (_h)->next, vxge_os_prefetch(_p->next); _p != (_h); \ 164221167Sgnn _p = _p->next, vxge_os_prefetch(_p->next)) 165221167Sgnn 166221167Sgnn#define vxge_list_for_each_safe(_p, _n, _h) \ 167221167Sgnn for (_p = (_h)->next, _n = _p->next; _p != (_h); \ 168221167Sgnn _p = _n, _n = _p->next) 169221167Sgnn 170221167Sgnn#define vxge_list_for_each_prev_safe(_p, _n, _h) \ 171221167Sgnn for (_p = (_h)->prev, _n = _p->prev; _p != (_h); \ 172221167Sgnn _p = _n, _n = _p->prev) 173221167Sgnn 174221167Sgnn#if defined(__GNUC__) 175221167Sgnn/* 176221167Sgnn * vxge_container_of - Given a member, return the containing structure. 177221167Sgnn * @ptr: the pointer to the member. 178221167Sgnn * @type: the type of the container struct this is embedded in. 179221167Sgnn * @member: the name of the member within the struct. 180221167Sgnn * 181221167Sgnn * Cast a member of a structure out to the containing structure. 182221167Sgnn */ 183221167Sgnn#define vxge_container_of(ptr, type, member) (\ 184221167Sgnn { __typeof(((type *)0)->member) *__mptr = (ptr); \ 185221167Sgnn (type *)(void *)((char *)__mptr - ((ptr_t)&((type *)0)->member)); }) 186221167Sgnn#else 187221167Sgnn/* type unsafe version */ 188221167Sgnn#define vxge_container_of(ptr, type, member) \ 189221167Sgnn ((type *)(void *)((char *)(ptr) - ((ptr_t)&((type *)0)->member))) 190221167Sgnn#endif 191221167Sgnn 192221167Sgnn/* 193221167Sgnn * vxge_offsetof - Offset of the member in the containing structure. 194221167Sgnn * @t: struct name. 195221167Sgnn * @m: the name of the member within the struct. 196221167Sgnn * 197221167Sgnn * Return the offset of the member @m in the structure @t. 198221167Sgnn */ 199221167Sgnn#define vxge_offsetof(t, m) ((ptr_t)(&((t *)0)->m)) 200221167Sgnn 201221167Sgnn__EXTERN_END_DECLS 202221167Sgnn 203221167Sgnn#endif /* VXGE_LIST_H */ 204