189495Snyan/*- 289495Snyan * Copyright(c) 2002-2011 Exar Corp. 389495Snyan * All rights reserved. 489495Snyan * 589495Snyan * Redistribution and use in source and binary forms, with or without 689495Snyan * modification are permitted provided the following conditions are met: 789495Snyan * 889495Snyan * 1. Redistributions of source code must retain the above copyright notice, 989495Snyan * this list of conditions and the following disclaimer. 1089495Snyan * 1189495Snyan * 2. Redistributions in binary form must reproduce the above copyright 1289495Snyan * notice, this list of conditions and the following disclaimer in the 1389495Snyan * documentation and/or other materials provided with the distribution. 1489495Snyan * 1589495Snyan * 3. Neither the name of the Exar Corporation nor the names of its 1689495Snyan * contributors may be used to endorse or promote products derived from 1789495Snyan * this software without specific prior written permission. 1889495Snyan * 1989495Snyan * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2089495Snyan * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2189495Snyan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2289495Snyan * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 2389495Snyan * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2489495Snyan * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2589495Snyan * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2689495Snyan * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2789495Snyan * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2889495Snyan * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2989495Snyan * POSSIBILITY OF SUCH DAMAGE. 3089495Snyan */ 3189495Snyan/*$FreeBSD$*/ 3289495Snyan 3389495Snyan#ifndef VXGE_LIST_H 3489495Snyan#define VXGE_LIST_H 3589495Snyan 3689495Snyan__EXTERN_BEGIN_DECLS 3789495Snyan 3889495Snyan/* 3989495Snyan * struct vxge_list_t - List item. 40103641Snyan * @prev: Previous list item. 4189495Snyan * @next: Next list item. 4289495Snyan * 4389495Snyan * Item of a bi-directional linked list. 44103641Snyan */ 4589495Snyantypedef struct vxge_list_t { 4689495Snyan struct vxge_list_t *prev; 4789495Snyan struct vxge_list_t *next; 4889495Snyan} vxge_list_t; 4989495Snyan 5089495Snyan/* 5189495Snyan * vxge_list_init - Initialize linked list. 5289495Snyan * @header: first element of the list (head) 5389495Snyan * 5489495Snyan * Initialize linked list. 5589495Snyan * See also: vxge_list_t {}. 5689495Snyan */ 5789495Snyanstatic inline void vxge_list_init(vxge_list_t *header) 5897065Snyan{ 5997065Snyan vxge_assert(header != NULL); 6089495Snyan 6189495Snyan header->next = header; 6289495Snyan header->prev = header; 6389495Snyan} 6489495Snyan 6597065Snyan/* 6689495Snyan * vxge_list_is_empty - Is the list empty? 6789495Snyan * @header: first element of the list (head) 6889495Snyan * 6989495Snyan * Determine whether the bi-directional list is empty. Return '1' in 7089495Snyan * case of 'empty'. 7189495Snyan * See also: vxge_list_t {}. 7289495Snyan */ 7389495Snyanstatic inline int vxge_list_is_empty(vxge_list_t *header) 7489495Snyan{ 7589495Snyan vxge_assert(header != NULL); 7689495Snyan 7789495Snyan return (header->next == header); 78200776Snyan} 79200776Snyan 80200776Snyan/* 81200776Snyan * vxge_list_first_get - Return the first item from the linked list. 82200776Snyan * @header: first element of the list (head) 83200776Snyan * 84200776Snyan * Returns the next item from the header. 85200776Snyan * Returns NULL if the next item is header itself 86200776Snyan * See also: vxge_list_remove(), vxge_list_insert(), vxge_list_t {}. 87200776Snyan */ 8889495Snyanstatic inline vxge_list_t *vxge_list_first_get(vxge_list_t *header) 8989495Snyan{ 90 vxge_assert(header != NULL); 91 vxge_assert(header->next != NULL); 92 vxge_assert(header->prev != NULL); 93 94 if (header->next == header) 95 return (NULL); 96 else 97 return (header->next); 98} 99 100/* 101 * vxge_list_remove - Remove the specified item from the linked list. 102 * @item: element of the list 103 * 104 * Remove item from a list. 105 * See also: vxge_list_insert(), vxge_list_t {}. 106 */ 107static inline void vxge_list_remove(vxge_list_t *item) 108{ 109 vxge_assert(item != NULL); 110 vxge_assert(item->next != NULL); 111 vxge_assert(item->prev != NULL); 112 113 item->next->prev = item->prev; 114 item->prev->next = item->next; 115#if defined(VXGE_DEBUG_ASSERT) 116 item->next = item->prev = NULL; 117#endif 118} 119 120/* 121 * vxge_list_insert - Insert a new item after the specified item. 122 * @new_item: new element of the list 123 * @prev_item: element of the list after which the new element is 124 * inserted 125 * 126 * Insert new item (new_item) after given item (prev_item). 127 * See also: vxge_list_remove(), vxge_list_insert_before(), vxge_list_t {}. 128 */ 129static inline void vxge_list_insert(vxge_list_t *new_item, 130 vxge_list_t *prev_item) 131{ 132 vxge_assert(new_item != NULL); 133 vxge_assert(prev_item != NULL); 134 vxge_assert(prev_item->next != NULL); 135 136 new_item->next = prev_item->next; 137 new_item->prev = prev_item; 138 prev_item->next->prev = new_item; 139 prev_item->next = new_item; 140} 141 142/* 143 * vxge_list_insert_before - Insert a new item before the specified item. 144 * @new_item: new element of the list 145 * @next_item: element of the list after which the new element is inserted 146 * 147 * Insert new item (new_item) before given item (next_item). 148 */ 149static inline void vxge_list_insert_before(vxge_list_t *new_item, 150 vxge_list_t * next_item) 151{ 152 vxge_assert(new_item != NULL); 153 vxge_assert(next_item != NULL); 154 vxge_assert(next_item->next != NULL); 155 156 new_item->next = next_item; 157 new_item->prev = next_item->prev; 158 next_item->prev->next = new_item; 159 next_item->prev = new_item; 160} 161 162#define vxge_list_for_each(_p, _h) \ 163 for (_p = (_h)->next, vxge_os_prefetch(_p->next); _p != (_h); \ 164 _p = _p->next, vxge_os_prefetch(_p->next)) 165 166#define vxge_list_for_each_safe(_p, _n, _h) \ 167 for (_p = (_h)->next, _n = _p->next; _p != (_h); \ 168 _p = _n, _n = _p->next) 169 170#define vxge_list_for_each_prev_safe(_p, _n, _h) \ 171 for (_p = (_h)->prev, _n = _p->prev; _p != (_h); \ 172 _p = _n, _n = _p->prev) 173 174#if defined(__GNUC__) 175/* 176 * vxge_container_of - Given a member, return the containing structure. 177 * @ptr: the pointer to the member. 178 * @type: the type of the container struct this is embedded in. 179 * @member: the name of the member within the struct. 180 * 181 * Cast a member of a structure out to the containing structure. 182 */ 183#define vxge_container_of(ptr, type, member) (\ 184 { __typeof(((type *)0)->member) *__mptr = (ptr); \ 185 (type *)(void *)((char *)__mptr - ((ptr_t)&((type *)0)->member)); }) 186#else 187/* type unsafe version */ 188#define vxge_container_of(ptr, type, member) \ 189 ((type *)(void *)((char *)(ptr) - ((ptr_t)&((type *)0)->member))) 190#endif 191 192/* 193 * vxge_offsetof - Offset of the member in the containing structure. 194 * @t: struct name. 195 * @m: the name of the member within the struct. 196 * 197 * Return the offset of the member @m in the structure @t. 198 */ 199#define vxge_offsetof(t, m) ((ptr_t)(&((t *)0)->m)) 200 201__EXTERN_END_DECLS 202 203#endif /* VXGE_LIST_H */ 204