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