1a23fd118Syl /*
2a23fd118Syl  * CDDL HEADER START
3a23fd118Syl  *
4a23fd118Syl  * The contents of this file are subject to the terms of the
5a23fd118Syl  * Common Development and Distribution License (the "License").
6a23fd118Syl  * You may not use this file except in compliance with the License.
7a23fd118Syl  *
8a23fd118Syl  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9a23fd118Syl  * or http://www.opensolaris.org/os/licensing.
10a23fd118Syl  * See the License for the specific language governing permissions
11a23fd118Syl  * and limitations under the License.
12a23fd118Syl  *
13a23fd118Syl  * When distributing Covered Code, include this CDDL HEADER in each
14a23fd118Syl  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15a23fd118Syl  * If applicable, add the following below this CDDL HEADER, with the
16a23fd118Syl  * fields enclosed by brackets "[]" replaced with your own identifying
17a23fd118Syl  * information: Portions Copyright [yyyy] [name of copyright owner]
18a23fd118Syl  *
19a23fd118Syl  * CDDL HEADER END
20a23fd118Syl  *
218347601bSyl  * Copyright (c) 2002-2006 Neterion, Inc.
22a23fd118Syl  */
23a23fd118Syl 
24a23fd118Syl #ifndef XGE_LIST_H
25a23fd118Syl #define XGE_LIST_H
26a23fd118Syl 
27a23fd118Syl #include "xge-debug.h"
28a23fd118Syl 
298347601bSyl __EXTERN_BEGIN_DECLS
308347601bSyl 
31a23fd118Syl /**
32a23fd118Syl  * struct xge_list_t - List item.
33a23fd118Syl  * @prev: Previous list item.
34a23fd118Syl  * @next: Next list item.
35a23fd118Syl  *
36a23fd118Syl  * Item of a bi-directional linked list.
37a23fd118Syl  */
38a23fd118Syl typedef struct xge_list_t {
39a23fd118Syl 	struct xge_list_t* prev;
40a23fd118Syl 	struct xge_list_t* next;
41a23fd118Syl } xge_list_t;
42a23fd118Syl 
43a23fd118Syl /**
44a23fd118Syl  * xge_list_init - Initialize linked list.
45a23fd118Syl  * header: first element of the list (head)
46a23fd118Syl  *
47a23fd118Syl  * Initialize linked list.
48a23fd118Syl  * See also: xge_list_t{}.
49a23fd118Syl  */
xge_list_init(xge_list_t * header)50a23fd118Syl static inline void xge_list_init (xge_list_t *header)
51a23fd118Syl {
52a23fd118Syl 	header->next = header;
53a23fd118Syl 	header->prev = header;
54a23fd118Syl }
55a23fd118Syl 
56a23fd118Syl /**
57a23fd118Syl  * xge_list_is_empty - Is the list empty?
58a23fd118Syl  * header: first element of the list (head)
59a23fd118Syl  *
60a23fd118Syl  * Determine whether the bi-directional list is empty. Return '1' in
61a23fd118Syl  * case of 'empty'.
62a23fd118Syl  * See also: xge_list_t{}.
63a23fd118Syl  */
xge_list_is_empty(xge_list_t * header)64a23fd118Syl static inline int xge_list_is_empty(xge_list_t *header)
65a23fd118Syl {
66a23fd118Syl     xge_assert(header != NULL);
67a23fd118Syl 
68a23fd118Syl     return header->next == header;
69a23fd118Syl }
70a23fd118Syl 
718347601bSyl /**
728347601bSyl  * xge_list_first_get - Return the first item from the linked list.
738347601bSyl  * header: first element of the list (head)
748347601bSyl  *
758347601bSyl  * Returns the next item from the header.
768347601bSyl  * Returns NULL if the next item is header itself
778347601bSyl  * See also: xge_list_remove(), xge_list_insert(), xge_list_t{}.
788347601bSyl  */
xge_list_first_get(xge_list_t * header)798347601bSyl static inline xge_list_t *xge_list_first_get(xge_list_t *header)
808347601bSyl {
818347601bSyl 	xge_assert(header != NULL);
828347601bSyl 	xge_assert(header->next != NULL);
838347601bSyl 	xge_assert(header->prev != NULL);
848347601bSyl 
858347601bSyl 	if(header->next == header)
868347601bSyl 		return NULL;
878347601bSyl 	else
888347601bSyl 		return header->next;
898347601bSyl }
908347601bSyl 
91a23fd118Syl /**
92a23fd118Syl  * xge_list_remove - Remove the specified item from the linked list.
93a23fd118Syl  * item: element of the list
94a23fd118Syl  *
95a23fd118Syl  * Remove item from a list.
96a23fd118Syl  * See also: xge_list_insert(), xge_list_t{}.
97a23fd118Syl  */
xge_list_remove(xge_list_t * item)98a23fd118Syl static inline void xge_list_remove(xge_list_t *item)
99a23fd118Syl {
100a23fd118Syl 	xge_assert(item != NULL);
101a23fd118Syl 	xge_assert(item->next != NULL);
102a23fd118Syl 	xge_assert(item->prev != NULL);
103a23fd118Syl 
104a23fd118Syl 	item->next->prev = item->prev;
105a23fd118Syl 	item->prev->next = item->next;
106a23fd118Syl #ifdef XGE_DEBUG_ASSERT
107a23fd118Syl 	item->next = item->prev = NULL;
108a23fd118Syl #endif
109a23fd118Syl }
110a23fd118Syl 
111a23fd118Syl /**
112a23fd118Syl  * xge_list_insert - Insert a new item after the specified item.
113a23fd118Syl  * new_item: new element of the list
114a23fd118Syl  * prev_item: element of the list after which the new element is
115a23fd118Syl  *             inserted
116a23fd118Syl  *
117a23fd118Syl  * Insert new item (new_item) after given item (prev_item).
118a23fd118Syl  * See also: xge_list_remove(), xge_list_insert_before(), xge_list_t{}.
119a23fd118Syl  */
xge_list_insert(xge_list_t * new_item,xge_list_t * prev_item)120a23fd118Syl static inline void xge_list_insert (xge_list_t *new_item,
121a23fd118Syl 				    xge_list_t *prev_item)
122a23fd118Syl {
123a23fd118Syl 	xge_assert(new_item  != NULL);
124a23fd118Syl 	xge_assert(prev_item != NULL);
125a23fd118Syl 	xge_assert(prev_item->next != NULL);
126a23fd118Syl 
127a23fd118Syl 	new_item->next = prev_item->next;
128a23fd118Syl 	new_item->prev = prev_item;
129a23fd118Syl 	prev_item->next->prev = new_item;
130a23fd118Syl 	prev_item->next = new_item;
131a23fd118Syl }
132a23fd118Syl 
133a23fd118Syl /**
134a23fd118Syl  * xge_list_insert_before - Insert a new item before the specified item.
135a23fd118Syl  * new_item: new element of the list
136a23fd118Syl  * next_item: element of the list after which the new element is inserted
137a23fd118Syl  *
138a23fd118Syl  * Insert new item (new_item) before given item (next_item).
139a23fd118Syl  */
xge_list_insert_before(xge_list_t * new_item,xge_list_t * next_item)140a23fd118Syl static inline void xge_list_insert_before (xge_list_t *new_item,
141a23fd118Syl 				    	   xge_list_t *next_item)
142a23fd118Syl {
143a23fd118Syl 	xge_assert(new_item  != NULL);
144a23fd118Syl 	xge_assert(next_item != NULL);
145a23fd118Syl 	xge_assert(next_item->next != NULL);
146a23fd118Syl 
147a23fd118Syl 	new_item->next = next_item;
148a23fd118Syl 	new_item->prev = next_item->prev;
149a23fd118Syl 	next_item->prev->next = new_item;
150a23fd118Syl 	next_item->prev = new_item;
151a23fd118Syl }
152a23fd118Syl 
153a23fd118Syl #define xge_list_for_each(_p, _h) \
154a23fd118Syl 	for (_p = (_h)->next, xge_os_prefetch(_p->next); _p != (_h); \
155a23fd118Syl 		_p = _p->next, xge_os_prefetch(_p->next))
156a23fd118Syl 
157a23fd118Syl #define xge_list_for_each_safe(_p, _n, _h) \
158a23fd118Syl         for (_p = (_h)->next, _n = _p->next; _p != (_h); \
159a23fd118Syl                 _p = _n, _n = _p->next)
160a23fd118Syl 
161a23fd118Syl #ifdef __GNUC__
162a23fd118Syl /**
163a23fd118Syl  * xge_container_of - Given a member, return the containing structure.
164a23fd118Syl  * @ptr:	the pointer to the member.
165a23fd118Syl  * @type:	the type of the container struct this is embedded in.
166a23fd118Syl  * @member:	the name of the member within the struct.
167a23fd118Syl  *
168a23fd118Syl  * Cast a member of a structure out to the containing structure.
169a23fd118Syl  */
170a23fd118Syl #define xge_container_of(ptr, type, member) ({			\
171*7eced415Sxw          __typeof( ((type *)0)->member ) *__mptr = (ptr);	\
172a23fd118Syl         (type *)(void *)( (char *)__mptr - ((size_t) &((type *)0)->member) );})
173a23fd118Syl #else
174a23fd118Syl /* type unsafe version */
175a23fd118Syl #define xge_container_of(ptr, type, member) \
176a23fd118Syl                 ((type*)(void*)((char*)(ptr) - ((size_t) &((type *)0)->member)))
177a23fd118Syl #endif
178a23fd118Syl 
179a23fd118Syl /**
180a23fd118Syl  * xge_offsetof - Offset of the member in the containing structure.
181a23fd118Syl  * @t:	struct name.
182a23fd118Syl  * @m:	the name of the member within the struct.
183a23fd118Syl  *
184a23fd118Syl  * Return the offset of the member @m in the structure @t.
185a23fd118Syl  */
186a23fd118Syl #define xge_offsetof(t, m) ((size_t) (&((t *)0)->m))
187a23fd118Syl 
1888347601bSyl __EXTERN_END_DECLS
1898347601bSyl 
190a23fd118Syl #endif /* XGE_LIST_H */
191