xref: /freebsd-11-stable/sys/dev/vxge/include/vxge-list.h (revision 4ab2e064d7950be84256d671a7ae93f87cc6aa36)
1 /*-
2  * Copyright(c) 2002-2011 Exar Corp.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification are permitted provided the following conditions are met:
7  *
8  *    1. Redistributions of source code must retain the above copyright notice,
9  *       this list of conditions and the following disclaimer.
10  *
11  *    2. Redistributions in binary form must reproduce the above copyright
12  *       notice, this list of conditions and the following disclaimer in the
13  *       documentation and/or other materials provided with the distribution.
14  *
15  *    3. Neither the name of the Exar Corporation nor the names of its
16  *       contributors may be used to endorse or promote products derived from
17  *       this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 /*$FreeBSD$*/
32 
33 #ifndef	VXGE_LIST_H
34 #define	VXGE_LIST_H
35 
36 __EXTERN_BEGIN_DECLS
37 
38 /*
39  * struct vxge_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 vxge_list_t {
46 	struct vxge_list_t		 *prev;
47 	struct vxge_list_t		 *next;
48 } vxge_list_t;
49 
50 /*
51  * vxge_list_init - Initialize linked list.
52  * @header: first element of the list (head)
53  *
54  * Initialize linked list.
55  * See also: vxge_list_t {}.
56  */
vxge_list_init(vxge_list_t * header)57 static inline void vxge_list_init(vxge_list_t *header)
58 {
59 	vxge_assert(header != NULL);
60 
61 	header->next = header;
62 	header->prev = header;
63 }
64 
65 /*
66  * vxge_list_is_empty - Is the list empty?
67  * @header: first element of the list (head)
68  *
69  * Determine whether the bi-directional list is empty. Return '1' in
70  * case of 'empty'.
71  * See also: vxge_list_t {}.
72  */
vxge_list_is_empty(vxge_list_t * header)73 static inline int vxge_list_is_empty(vxge_list_t *header)
74 {
75 	vxge_assert(header != NULL);
76 
77 	return (header->next == header);
78 }
79 
80 /*
81  * vxge_list_first_get - Return the first item from the linked list.
82  * @header: first element of the list (head)
83  *
84  * Returns the next item from the header.
85  * Returns NULL if the next item is header itself
86  * See also: vxge_list_remove(), vxge_list_insert(), vxge_list_t {}.
87  */
vxge_list_first_get(vxge_list_t * header)88 static inline vxge_list_t *vxge_list_first_get(vxge_list_t *header)
89 {
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  */
vxge_list_remove(vxge_list_t * item)107 static 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  */
vxge_list_insert(vxge_list_t * new_item,vxge_list_t * prev_item)129 static 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  */
vxge_list_insert_before(vxge_list_t * new_item,vxge_list_t * next_item)149 static 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