xref: /illumos-gate/usr/src/uts/common/io/xge/hal/include/xge-list.h (revision a23fd118e437af0a7877dd313db8fdaa3537c675)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  *  Copyright (c) 2002-2005 Neterion, Inc.
24  *  All right Reserved.
25  *
26  *  FileName :    xge-list.h
27  *
28  *  Description:  Generic bi-directional linked list implementation
29  *
30  *  Created:      14 May 2004
31  */
32 
33 #ifndef XGE_LIST_H
34 #define XGE_LIST_H
35 
36 #include "xge-debug.h"
37 
38 /**
39  * struct xge_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 xge_list_t {
46 	struct xge_list_t* prev;
47 	struct xge_list_t* next;
48 } xge_list_t;
49 
50 /**
51  * xge_list_init - Initialize linked list.
52  * header: first element of the list (head)
53  *
54  * Initialize linked list.
55  * See also: xge_list_t{}.
56  */
57 static inline void xge_list_init (xge_list_t *header)
58 {
59 	header->next = header;
60 	header->prev = header;
61 }
62 
63 /**
64  * xge_list_is_empty - Is the list empty?
65  * header: first element of the list (head)
66  *
67  * Determine whether the bi-directional list is empty. Return '1' in
68  * case of 'empty'.
69  * See also: xge_list_t{}.
70  */
71 static inline int xge_list_is_empty(xge_list_t *header)
72 {
73     xge_assert(header != NULL);
74 
75     return header->next == header;
76 }
77 
78 /**
79  * xge_list_remove - Remove the specified item from the linked list.
80  * item: element of the list
81  *
82  * Remove item from a list.
83  * See also: xge_list_insert(), xge_list_t{}.
84  */
85 static inline void xge_list_remove(xge_list_t *item)
86 {
87 	xge_assert(item != NULL);
88 	xge_assert(item->next != NULL);
89 	xge_assert(item->prev != NULL);
90 
91 	item->next->prev = item->prev;
92 	item->prev->next = item->next;
93 #ifdef XGE_DEBUG_ASSERT
94 	item->next = item->prev = NULL;
95 #endif
96 }
97 
98 /**
99  * xge_list_insert - Insert a new item after the specified item.
100  * new_item: new element of the list
101  * prev_item: element of the list after which the new element is
102  *             inserted
103  *
104  * Insert new item (new_item) after given item (prev_item).
105  * See also: xge_list_remove(), xge_list_insert_before(), xge_list_t{}.
106  */
107 static inline void xge_list_insert (xge_list_t *new_item,
108 				    xge_list_t *prev_item)
109 {
110 	xge_assert(new_item  != NULL);
111 	xge_assert(prev_item != NULL);
112 	xge_assert(prev_item->next != NULL);
113 
114 	new_item->next = prev_item->next;
115 	new_item->prev = prev_item;
116 	prev_item->next->prev = new_item;
117 	prev_item->next = new_item;
118 }
119 
120 /**
121  * xge_list_insert_before - Insert a new item before the specified item.
122  * new_item: new element of the list
123  * next_item: element of the list after which the new element is inserted
124  *
125  * Insert new item (new_item) before given item (next_item).
126  */
127 static inline void xge_list_insert_before (xge_list_t *new_item,
128 				    	   xge_list_t *next_item)
129 {
130 	xge_assert(new_item  != NULL);
131 	xge_assert(next_item != NULL);
132 	xge_assert(next_item->next != NULL);
133 
134 	new_item->next = next_item;
135 	new_item->prev = next_item->prev;
136 	next_item->prev->next = new_item;
137 	next_item->prev = new_item;
138 }
139 
140 #define xge_list_for_each(_p, _h) \
141 	for (_p = (_h)->next, xge_os_prefetch(_p->next); _p != (_h); \
142 		_p = _p->next, xge_os_prefetch(_p->next))
143 
144 #define xge_list_for_each_safe(_p, _n, _h) \
145         for (_p = (_h)->next, _n = _p->next; _p != (_h); \
146                 _p = _n, _n = _p->next)
147 
148 #ifdef __GNUC__
149 /**
150  * xge_container_of - Given a member, return the containing structure.
151  * @ptr:	the pointer to the member.
152  * @type:	the type of the container struct this is embedded in.
153  * @member:	the name of the member within the struct.
154  *
155  * Cast a member of a structure out to the containing structure.
156  */
157 #define xge_container_of(ptr, type, member) ({			\
158         const __typeof( ((type *)0)->member ) *__mptr = (ptr);	\
159         (type *)(void *)( (char *)__mptr - ((size_t) &((type *)0)->member) );})
160 #else
161 /* type unsafe version */
162 #define xge_container_of(ptr, type, member) \
163                 ((type*)(void*)((char*)(ptr) - ((size_t) &((type *)0)->member)))
164 #endif
165 
166 /**
167  * xge_offsetof - Offset of the member in the containing structure.
168  * @t:	struct name.
169  * @m:	the name of the member within the struct.
170  *
171  * Return the offset of the member @m in the structure @t.
172  */
173 #define xge_offsetof(t, m) ((size_t) (&((t *)0)->m))
174 
175 #endif /* XGE_LIST_H */
176