1171095Ssam/*-
2171095Ssam * Copyright (c) 2002-2007 Neterion, Inc.
3171095Ssam * All rights reserved.
4171095Ssam *
5171095Ssam * Redistribution and use in source and binary forms, with or without
6171095Ssam * modification, are permitted provided that the following conditions
7171095Ssam * are met:
8171095Ssam * 1. Redistributions of source code must retain the above copyright
9171095Ssam *    notice, this list of conditions and the following disclaimer.
10171095Ssam * 2. Redistributions in binary form must reproduce the above copyright
11171095Ssam *    notice, this list of conditions and the following disclaimer in the
12171095Ssam *    documentation and/or other materials provided with the distribution.
13171095Ssam *
14171095Ssam * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15171095Ssam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16171095Ssam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17171095Ssam * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18171095Ssam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19171095Ssam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20171095Ssam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21171095Ssam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22171095Ssam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23171095Ssam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24171095Ssam * SUCH DAMAGE.
25171095Ssam *
26171095Ssam * $FreeBSD$
27171095Ssam */
28171095Ssam
29171095Ssam#ifndef XGE_LIST_H
30171095Ssam#define XGE_LIST_H
31171095Ssam
32171095Ssam#include <dev/nxge/include/xge-debug.h>
33171095Ssam
34171095Ssam__EXTERN_BEGIN_DECLS
35171095Ssam
36171095Ssam/**
37171095Ssam * struct xge_list_t - List item.
38171095Ssam * @prev: Previous list item.
39171095Ssam * @next: Next list item.
40171095Ssam *
41171095Ssam * Item of a bi-directional linked list.
42171095Ssam */
43171095Ssamtypedef struct xge_list_t {
44171095Ssam	struct xge_list_t* prev;
45171095Ssam	struct xge_list_t* next;
46171095Ssam} xge_list_t;
47171095Ssam
48171095Ssam/**
49171095Ssam * xge_list_init - Initialize linked list.
50171095Ssam * header: first element of the list (head)
51171095Ssam *
52171095Ssam * Initialize linked list.
53171095Ssam * See also: xge_list_t{}.
54171095Ssam */
55171095Ssamstatic inline void xge_list_init (xge_list_t *header)
56171095Ssam{
57171095Ssam	header->next = header;
58171095Ssam	header->prev = header;
59171095Ssam}
60171095Ssam
61171095Ssam/**
62171095Ssam * xge_list_is_empty - Is the list empty?
63171095Ssam * header: first element of the list (head)
64171095Ssam *
65171095Ssam * Determine whether the bi-directional list is empty. Return '1' in
66171095Ssam * case of 'empty'.
67171095Ssam * See also: xge_list_t{}.
68171095Ssam */
69171095Ssamstatic inline int xge_list_is_empty(xge_list_t *header)
70171095Ssam{
71173139Srwatson	xge_assert(header != NULL);
72171095Ssam
73173139Srwatson	return header->next == header;
74171095Ssam}
75171095Ssam
76171095Ssam/**
77171095Ssam * xge_list_first_get - Return the first item from the linked list.
78171095Ssam * header: first element of the list (head)
79171095Ssam *
80171095Ssam * Returns the next item from the header.
81171095Ssam * Returns NULL if the next item is header itself
82171095Ssam * See also: xge_list_remove(), xge_list_insert(), xge_list_t{}.
83171095Ssam */
84171095Ssamstatic inline xge_list_t *xge_list_first_get(xge_list_t *header)
85171095Ssam{
86171095Ssam	xge_assert(header != NULL);
87171095Ssam	xge_assert(header->next != NULL);
88171095Ssam	xge_assert(header->prev != NULL);
89171095Ssam
90171095Ssam	if(header->next == header)
91173139Srwatson	    return NULL;
92171095Ssam	else
93173139Srwatson	    return header->next;
94171095Ssam}
95171095Ssam
96171095Ssam/**
97171095Ssam * xge_list_remove - Remove the specified item from the linked list.
98171095Ssam * item: element of the list
99171095Ssam *
100171095Ssam * Remove item from a list.
101171095Ssam * See also: xge_list_insert(), xge_list_t{}.
102171095Ssam */
103171095Ssamstatic inline void xge_list_remove(xge_list_t *item)
104171095Ssam{
105171095Ssam	xge_assert(item != NULL);
106171095Ssam	xge_assert(item->next != NULL);
107171095Ssam	xge_assert(item->prev != NULL);
108171095Ssam
109171095Ssam	item->next->prev = item->prev;
110171095Ssam	item->prev->next = item->next;
111171095Ssam#ifdef XGE_DEBUG_ASSERT
112171095Ssam	item->next = item->prev = NULL;
113171095Ssam#endif
114171095Ssam}
115171095Ssam
116171095Ssam/**
117171095Ssam * xge_list_insert - Insert a new item after the specified item.
118171095Ssam * new_item: new element of the list
119171095Ssam * prev_item: element of the list after which the new element is
120171095Ssam *             inserted
121171095Ssam *
122171095Ssam * Insert new item (new_item) after given item (prev_item).
123171095Ssam * See also: xge_list_remove(), xge_list_insert_before(), xge_list_t{}.
124171095Ssam */
125171095Ssamstatic inline void xge_list_insert (xge_list_t *new_item,
126173139Srwatson	                xge_list_t *prev_item)
127171095Ssam{
128171095Ssam	xge_assert(new_item  != NULL);
129171095Ssam	xge_assert(prev_item != NULL);
130171095Ssam	xge_assert(prev_item->next != NULL);
131171095Ssam
132171095Ssam	new_item->next = prev_item->next;
133171095Ssam	new_item->prev = prev_item;
134171095Ssam	prev_item->next->prev = new_item;
135171095Ssam	prev_item->next = new_item;
136171095Ssam}
137171095Ssam
138171095Ssam/**
139171095Ssam * xge_list_insert_before - Insert a new item before the specified item.
140171095Ssam * new_item: new element of the list
141171095Ssam * next_item: element of the list after which the new element is inserted
142171095Ssam *
143171095Ssam * Insert new item (new_item) before given item (next_item).
144171095Ssam */
145171095Ssamstatic inline void xge_list_insert_before (xge_list_t *new_item,
146173139Srwatson	                       xge_list_t *next_item)
147171095Ssam{
148171095Ssam	xge_assert(new_item  != NULL);
149171095Ssam	xge_assert(next_item != NULL);
150171095Ssam	xge_assert(next_item->next != NULL);
151171095Ssam
152171095Ssam	new_item->next = next_item;
153171095Ssam	new_item->prev = next_item->prev;
154171095Ssam	next_item->prev->next = new_item;
155171095Ssam	next_item->prev = new_item;
156171095Ssam}
157171095Ssam
158171095Ssam#define xge_list_for_each(_p, _h) \
159171095Ssam	for (_p = (_h)->next, xge_os_prefetch(_p->next); _p != (_h); \
160173139Srwatson	    _p = _p->next, xge_os_prefetch(_p->next))
161171095Ssam
162171095Ssam#define xge_list_for_each_safe(_p, _n, _h) \
163173139Srwatson	    for (_p = (_h)->next, _n = _p->next; _p != (_h); \
164173139Srwatson	            _p = _n, _n = _p->next)
165171095Ssam
166171095Ssam#ifdef __GNUC__
167171095Ssam/**
168171095Ssam * xge_container_of - Given a member, return the containing structure.
169173139Srwatson * @ptr:    the pointer to the member.
170173139Srwatson * @type:   the type of the container struct this is embedded in.
171173139Srwatson * @member: the name of the member within the struct.
172171095Ssam *
173171095Ssam * Cast a member of a structure out to the containing structure.
174171095Ssam */
175173139Srwatson#define xge_container_of(ptr, type, member) ({          \
176173139Srwatson	     __typeof( ((type *)0)->member ) *__mptr = (ptr);   \
177173139Srwatson	    (type *)(void *)( (char *)__mptr - ((size_t) &((type *)0)->member) );})
178171095Ssam#else
179171095Ssam/* type unsafe version */
180171095Ssam#define xge_container_of(ptr, type, member) \
181173139Srwatson	            ((type*)(void*)((char*)(ptr) - ((size_t) &((type *)0)->member)))
182171095Ssam#endif
183171095Ssam
184171095Ssam/**
185171095Ssam * xge_offsetof - Offset of the member in the containing structure.
186173139Srwatson * @t:  struct name.
187173139Srwatson * @m:  the name of the member within the struct.
188171095Ssam *
189171095Ssam * Return the offset of the member @m in the structure @t.
190171095Ssam */
191171095Ssam#define xge_offsetof(t, m) ((size_t) (&((t *)0)->m))
192171095Ssam
193171095Ssam__EXTERN_END_DECLS
194171095Ssam
195171095Ssam#endif /* XGE_LIST_H */
196