list.h revision 276749
1/*-
2 * Copyright (c) 2010 Isilon Systems, Inc.
3 * Copyright (c) 2010 iX Systems, Inc.
4 * Copyright (c) 2010 Panasas, Inc.
5 * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice unmodified, this list of conditions, and the following
13 *    disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29#ifndef _LINUX_LIST_H_
30#define _LINUX_LIST_H_
31
32/*
33 * Since LIST_HEAD conflicts with the linux definition we must include any
34 * FreeBSD header which requires it here so it is resolved with the correct
35 * definition prior to the undef.
36 */
37#include <linux/types.h>
38
39#include <sys/param.h>
40#include <sys/kernel.h>
41#include <sys/queue.h>
42#include <sys/cpuset.h>
43#include <sys/jail.h>
44#include <sys/lock.h>
45#include <sys/mutex.h>
46#include <sys/proc.h>
47#include <sys/vnode.h>
48#include <sys/conf.h>
49#include <sys/socket.h>
50#include <sys/mbuf.h>
51
52#include <net/bpf.h>
53#include <net/if.h>
54#include <net/if_var.h>
55#include <net/if_types.h>
56#include <net/if_media.h>
57#include <net/vnet.h>
58
59#include <netinet/in.h>
60#include <netinet/in_pcb.h>
61#include <netinet/in_var.h>
62
63#include <netinet6/in6_var.h>
64#include <netinet6/nd6.h>
65
66#include <vm/vm.h>
67#include <vm/vm_object.h>
68
69#define	prefetch(x)
70
71struct list_head {
72	struct list_head *next;
73	struct list_head *prev;
74};
75
76static inline void
77INIT_LIST_HEAD(struct list_head *list)
78{
79
80	list->next = list->prev = list;
81}
82
83static inline int
84list_empty(const struct list_head *head)
85{
86
87	return (head->next == head);
88}
89
90static inline void
91list_del(struct list_head *entry)
92{
93
94	entry->next->prev = entry->prev;
95	entry->prev->next = entry->next;
96}
97
98static inline void
99_list_add(struct list_head *new, struct list_head *prev,
100    struct list_head *next)
101{
102
103	next->prev = new;
104	new->next = next;
105	new->prev = prev;
106	prev->next = new;
107}
108
109static inline void
110list_del_init(struct list_head *entry)
111{
112
113	list_del(entry);
114	INIT_LIST_HEAD(entry);
115}
116
117#define	list_entry(ptr, type, field)	container_of(ptr, type, field)
118
119#define list_first_entry(ptr, type, member) \
120        list_entry((ptr)->next, type, member)
121
122#define	list_for_each(p, head)						\
123	for (p = (head)->next; p != (head); p = p->next)
124
125#define	list_for_each_safe(p, n, head)					\
126	for (p = (head)->next, n = p->next; p != (head); p = n, n = p->next)
127
128#define list_for_each_entry(p, h, field)				\
129	for (p = list_entry((h)->next, typeof(*p), field); &p->field != (h); \
130	    p = list_entry(p->field.next, typeof(*p), field))
131
132#define list_for_each_entry_safe(p, n, h, field)			\
133	for (p = list_entry((h)->next, typeof(*p), field), 		\
134	    n = list_entry(p->field.next, typeof(*p), field); &p->field != (h);\
135	    p = n, n = list_entry(n->field.next, typeof(*n), field))
136
137#define	list_for_each_entry_reverse(p, h, field)			\
138	for (p = list_entry((h)->prev, typeof(*p), field); &p->field != (h); \
139	    p = list_entry(p->field.prev, typeof(*p), field))
140
141#define	list_for_each_prev(p, h) for (p = (h)->prev; p != (h); p = p->prev)
142
143static inline void
144list_add(struct list_head *new, struct list_head *head)
145{
146
147	_list_add(new, head, head->next);
148}
149
150static inline void
151list_add_tail(struct list_head *new, struct list_head *head)
152{
153
154	_list_add(new, head->prev, head);
155}
156
157static inline void
158list_move(struct list_head *list, struct list_head *head)
159{
160
161	list_del(list);
162	list_add(list, head);
163}
164
165static inline void
166list_move_tail(struct list_head *entry, struct list_head *head)
167{
168
169	list_del(entry);
170	list_add_tail(entry, head);
171}
172
173static inline void
174_list_splice(const struct list_head *list, struct list_head *prev,
175    struct list_head *next)
176{
177	struct list_head *first;
178	struct list_head *last;
179
180	if (list_empty(list))
181		return;
182	first = list->next;
183	last = list->prev;
184	first->prev = prev;
185	prev->next = first;
186	last->next = next;
187	next->prev = last;
188}
189
190static inline void
191list_splice(const struct list_head *list, struct list_head *head)
192{
193
194	_list_splice(list, head, head->next);
195}
196
197static inline void
198list_splice_tail(struct list_head *list, struct list_head *head)
199{
200
201	_list_splice(list, head->prev, head);
202}
203
204static inline void
205list_splice_init(struct list_head *list, struct list_head *head)
206{
207
208	_list_splice(list, head, head->next);
209	INIT_LIST_HEAD(list);
210}
211
212static inline void
213list_splice_tail_init(struct list_head *list, struct list_head *head)
214{
215
216	_list_splice(list, head->prev, head);
217	INIT_LIST_HEAD(list);
218}
219
220#undef LIST_HEAD
221#define LIST_HEAD(name)	struct list_head name = { &(name), &(name) }
222
223
224struct hlist_head {
225	struct hlist_node *first;
226};
227
228struct hlist_node {
229	struct hlist_node *next, **pprev;
230};
231
232#define	HLIST_HEAD_INIT { }
233#define	HLIST_HEAD(name) struct hlist_head name = HLIST_HEAD_INIT
234#define	INIT_HLIST_HEAD(head) (head)->first = NULL
235#define	INIT_HLIST_NODE(node)						\
236do {									\
237	(node)->next = NULL;						\
238	(node)->pprev = NULL;						\
239} while (0)
240
241static inline int
242hlist_unhashed(const struct hlist_node *h)
243{
244
245	return !h->pprev;
246}
247
248static inline int
249hlist_empty(const struct hlist_head *h)
250{
251
252	return !h->first;
253}
254
255static inline void
256hlist_del(struct hlist_node *n)
257{
258
259        if (n->next)
260                n->next->pprev = n->pprev;
261        *n->pprev = n->next;
262}
263
264static inline void
265hlist_del_init(struct hlist_node *n)
266{
267
268	if (hlist_unhashed(n))
269		return;
270	hlist_del(n);
271	INIT_HLIST_NODE(n);
272}
273
274static inline void
275hlist_add_head(struct hlist_node *n, struct hlist_head *h)
276{
277
278	n->next = h->first;
279	if (h->first)
280		h->first->pprev = &n->next;
281	h->first = n;
282	n->pprev = &h->first;
283}
284
285static inline void
286hlist_add_before(struct hlist_node *n, struct hlist_node *next)
287{
288
289	n->pprev = next->pprev;
290	n->next = next;
291	next->pprev = &n->next;
292	*(n->pprev) = n;
293}
294
295static inline void
296hlist_add_after(struct hlist_node *n, struct hlist_node *next)
297{
298
299	next->next = n->next;
300	n->next = next;
301	next->pprev = &n->next;
302	if (next->next)
303		next->next->pprev = &next->next;
304}
305
306static inline void
307hlist_move_list(struct hlist_head *old, struct hlist_head *new)
308{
309
310	new->first = old->first;
311	if (new->first)
312		new->first->pprev = &new->first;
313	old->first = NULL;
314}
315
316/**
317 * list_is_singular - tests whether a list has just one entry.
318 * @head: the list to test.
319 */
320static inline int list_is_singular(const struct list_head *head)
321{
322	return !list_empty(head) && (head->next == head->prev);
323}
324
325static inline void __list_cut_position(struct list_head *list,
326		struct list_head *head, struct list_head *entry)
327{
328	struct list_head *new_first = entry->next;
329	list->next = head->next;
330	list->next->prev = list;
331	list->prev = entry;
332	entry->next = list;
333	head->next = new_first;
334	new_first->prev = head;
335}
336
337/**
338 * list_cut_position - cut a list into two
339 * @list: a new list to add all removed entries
340 * @head: a list with entries
341 * @entry: an entry within head, could be the head itself
342 *	and if so we won't cut the list
343 *
344 * This helper moves the initial part of @head, up to and
345 * including @entry, from @head to @list. You should
346 * pass on @entry an element you know is on @head. @list
347 * should be an empty list or a list you do not care about
348 * losing its data.
349 *
350 */
351static inline void list_cut_position(struct list_head *list,
352		struct list_head *head, struct list_head *entry)
353{
354	if (list_empty(head))
355		return;
356	if (list_is_singular(head) &&
357		(head->next != entry && head != entry))
358		return;
359	if (entry == head)
360		INIT_LIST_HEAD(list);
361	else
362		__list_cut_position(list, head, entry);
363}
364
365/**
366 *  list_is_last - tests whether @list is the last entry in list @head
367 *   @list: the entry to test
368 *    @head: the head of the list
369 */
370static inline int list_is_last(const struct list_head *list,
371                                const struct list_head *head)
372{
373        return list->next == head;
374}
375
376#define	hlist_entry(ptr, type, field)	container_of(ptr, type, field)
377
378#define	hlist_for_each(p, head)						\
379	for (p = (head)->first; p; p = p->next)
380
381#define	hlist_for_each_safe(p, n, head)					\
382	for (p = (head)->first; p && ({ n = p->next; 1; }); p = n)
383
384#define	hlist_for_each_entry(tp, p, head, field)			\
385	for (p = (head)->first;						\
386	    p ? (tp = hlist_entry(p, typeof(*tp), field)): NULL; p = p->next)
387
388#define hlist_for_each_entry_continue(tp, p, field)			\
389	for (p = (p)->next;						\
390	    p ? (tp = hlist_entry(p, typeof(*tp), field)): NULL; p = p->next)
391
392#define	hlist_for_each_entry_from(tp, p, field)				\
393	for (; p ? (tp = hlist_entry(p, typeof(*tp), field)): NULL; p = p->next)
394
395#define hlist_for_each_entry_safe(tpos, pos, n, head, member) 		 \
396	for (pos = (head)->first;					 \
397	     (pos) != 0 && ({ n = (pos)->next; \
398		 tpos = hlist_entry((pos), typeof(*(tpos)), member); 1;}); \
399	     pos = (n))
400
401#endif /* _LINUX_LIST_H_ */
402