Home | History | Annotate | Line # | Download | only in linux
      1  1.32  riastrad /*	$NetBSD: list.h,v 1.32 2021/12/19 11:39:24 riastradh Exp $	*/
      2   1.1     skrll 
      3   1.1     skrll /*-
      4   1.1     skrll  * Copyright (c) 2013 The NetBSD Foundation, Inc.
      5   1.1     skrll  * All rights reserved.
      6   1.1     skrll  *
      7   1.1     skrll  * This code is derived from software contributed to The NetBSD Foundation
      8   1.1     skrll  * by Taylor R. Campbell.
      9   1.1     skrll  *
     10   1.1     skrll  * Redistribution and use in source and binary forms, with or without
     11   1.1     skrll  * modification, are permitted provided that the following conditions
     12   1.1     skrll  * are met:
     13   1.1     skrll  * 1. Redistributions of source code must retain the above copyright
     14   1.1     skrll  *    notice, this list of conditions and the following disclaimer.
     15   1.1     skrll  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1     skrll  *    notice, this list of conditions and the following disclaimer in the
     17   1.1     skrll  *    documentation and/or other materials provided with the distribution.
     18   1.1     skrll  *
     19   1.1     skrll  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20   1.1     skrll  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21   1.1     skrll  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22   1.1     skrll  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23   1.1     skrll  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24   1.1     skrll  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25   1.1     skrll  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26   1.1     skrll  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27   1.1     skrll  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28   1.1     skrll  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29   1.1     skrll  * POSSIBILITY OF SUCH DAMAGE.
     30   1.1     skrll  */
     31   1.1     skrll 
     32   1.2  riastrad /*
     33   1.2  riastrad  * Notes on porting:
     34   1.2  riastrad  *
     35   1.2  riastrad  * - LIST_HEAD(x) means a declaration `struct list_head x =
     36   1.2  riastrad  *   LIST_HEAD_INIT(x)' in Linux, but something else in NetBSD.
     37   1.2  riastrad  *   Replace by the expansion.
     38   1.2  riastrad  */
     39   1.2  riastrad 
     40   1.1     skrll #ifndef _LINUX_LIST_H_
     41   1.1     skrll #define _LINUX_LIST_H_
     42   1.1     skrll 
     43   1.1     skrll #include <sys/null.h>
     44   1.7  riastrad #include <sys/pslist.h>
     45   1.1     skrll #include <sys/queue.h>
     46   1.1     skrll 
     47   1.1     skrll #include <linux/kernel.h>
     48  1.20  riastrad #include <linux/types.h>
     49   1.1     skrll 
     50  1.32  riastrad #define	POISON_INUSE	0x5a	/* XXX */
     51  1.32  riastrad 
     52   1.1     skrll /*
     53  1.20  riastrad  * Doubly-linked lists.  Type defined in <linux/types.h>.
     54   1.1     skrll  */
     55   1.1     skrll 
     56   1.1     skrll #define	LIST_HEAD_INIT(name)	{ .prev = &(name), .next = &(name) }
     57   1.1     skrll 
     58  1.19  riastrad #define	LINUX_LIST_HEAD(name)	struct list_head name = LIST_HEAD_INIT(name)
     59  1.19  riastrad 
     60   1.1     skrll static inline void
     61   1.1     skrll INIT_LIST_HEAD(struct list_head *head)
     62   1.1     skrll {
     63   1.1     skrll 	head->prev = head;
     64   1.1     skrll 	head->next = head;
     65   1.1     skrll }
     66   1.1     skrll 
     67   1.1     skrll static inline struct list_head *
     68   1.1     skrll list_first(const struct list_head *head)
     69   1.1     skrll {
     70   1.1     skrll 	return head->next;
     71   1.1     skrll }
     72   1.1     skrll 
     73   1.1     skrll static inline struct list_head *
     74   1.5  riastrad list_last(const struct list_head *head)
     75   1.5  riastrad {
     76   1.5  riastrad 	return head->prev;
     77   1.5  riastrad }
     78   1.5  riastrad 
     79   1.5  riastrad static inline struct list_head *
     80   1.1     skrll list_next(const struct list_head *node)
     81   1.1     skrll {
     82   1.1     skrll 	return node->next;
     83   1.1     skrll }
     84   1.1     skrll 
     85   1.1     skrll static inline struct list_head *
     86   1.1     skrll list_prev(const struct list_head *node)
     87   1.1     skrll {
     88   1.1     skrll 	return node->prev;
     89   1.1     skrll }
     90   1.1     skrll 
     91   1.1     skrll static inline int
     92   1.1     skrll list_empty(const struct list_head *head)
     93   1.1     skrll {
     94   1.1     skrll 	return (head->next == head);
     95   1.1     skrll }
     96   1.1     skrll 
     97   1.3  riastrad static inline int
     98   1.3  riastrad list_is_singular(const struct list_head *head)
     99   1.3  riastrad {
    100   1.3  riastrad 
    101   1.3  riastrad 	if (list_empty(head))
    102   1.3  riastrad 		return false;
    103   1.3  riastrad 	if (head->next != head->prev)
    104   1.3  riastrad 		return false;
    105   1.3  riastrad 	return true;
    106   1.3  riastrad }
    107   1.3  riastrad 
    108  1.22  riastrad static inline bool
    109  1.23  riastrad list_is_first(const struct list_head *entry, const struct list_head *head)
    110  1.23  riastrad {
    111  1.23  riastrad 	return head == entry->prev;
    112  1.23  riastrad }
    113  1.23  riastrad 
    114  1.23  riastrad static inline bool
    115  1.22  riastrad list_is_last(const struct list_head *entry, const struct list_head *head)
    116  1.22  riastrad {
    117  1.22  riastrad 	return head == entry->next;
    118  1.22  riastrad }
    119  1.22  riastrad 
    120   1.1     skrll static inline void
    121   1.1     skrll __list_add_between(struct list_head *prev, struct list_head *node,
    122   1.1     skrll     struct list_head *next)
    123   1.1     skrll {
    124   1.1     skrll 	prev->next = node;
    125   1.1     skrll 	node->prev = prev;
    126   1.1     skrll 	node->next = next;
    127   1.1     skrll 	next->prev = node;
    128   1.1     skrll }
    129   1.1     skrll 
    130   1.1     skrll static inline void
    131   1.1     skrll list_add(struct list_head *node, struct list_head *head)
    132   1.1     skrll {
    133   1.1     skrll 	__list_add_between(head, node, head->next);
    134   1.1     skrll }
    135   1.1     skrll 
    136   1.1     skrll static inline void
    137  1.30  riastrad list_add_rcu(struct list_head *node, struct list_head *head)
    138  1.30  riastrad {
    139  1.30  riastrad 	struct list_head *next = head->next;
    140  1.30  riastrad 
    141  1.30  riastrad 	/* Initialize the new node first.  */
    142  1.30  riastrad 	node->next = next;
    143  1.30  riastrad 	node->prev = head;
    144  1.30  riastrad 
    145  1.30  riastrad 	/* Now publish it.  */
    146  1.30  riastrad 	atomic_store_release(&head->next, node);
    147  1.30  riastrad 
    148  1.30  riastrad 	/* Fix up back pointers, not protected by RCU.  */
    149  1.30  riastrad 	next->prev = node;
    150  1.30  riastrad }
    151  1.30  riastrad 
    152  1.30  riastrad static inline void
    153   1.1     skrll list_add_tail(struct list_head *node, struct list_head *head)
    154   1.1     skrll {
    155   1.1     skrll 	__list_add_between(head->prev, node, head);
    156   1.1     skrll }
    157   1.1     skrll 
    158   1.1     skrll static inline void
    159  1.21  riastrad __list_del_entry(struct list_head *entry)
    160   1.1     skrll {
    161   1.1     skrll 	entry->prev->next = entry->next;
    162   1.1     skrll 	entry->next->prev = entry->prev;
    163   1.1     skrll }
    164   1.1     skrll 
    165   1.1     skrll static inline void
    166  1.21  riastrad list_del(struct list_head *entry)
    167  1.21  riastrad {
    168  1.21  riastrad 	__list_del_entry(entry);
    169  1.21  riastrad 	entry->next = (void *)(uintptr_t)1;
    170  1.21  riastrad 	entry->prev = (void *)(uintptr_t)2;
    171  1.21  riastrad }
    172  1.21  riastrad 
    173  1.21  riastrad static inline void
    174   1.1     skrll __list_splice_between(struct list_head *prev, const struct list_head *list,
    175   1.1     skrll     struct list_head *next)
    176   1.1     skrll {
    177   1.1     skrll 	struct list_head *first = list->next;
    178   1.1     skrll 	struct list_head *last = list->prev;
    179   1.1     skrll 
    180   1.1     skrll 	first->prev = prev;
    181   1.1     skrll 	prev->next = first;
    182   1.1     skrll 
    183   1.1     skrll 	last->next = next;
    184   1.1     skrll 	next->prev = last;
    185   1.1     skrll }
    186   1.1     skrll 
    187   1.1     skrll static inline void
    188   1.1     skrll list_splice(const struct list_head *list, struct list_head *head)
    189   1.1     skrll {
    190   1.1     skrll 	if (!list_empty(list))
    191   1.1     skrll 		__list_splice_between(head, list, head->next);
    192   1.1     skrll }
    193   1.1     skrll 
    194   1.1     skrll static inline void
    195  1.18  riastrad list_splice_init(struct list_head *list, struct list_head *head)
    196  1.18  riastrad {
    197  1.18  riastrad 	if (!list_empty(list)) {
    198  1.18  riastrad 		__list_splice_between(head, list, head->next);
    199  1.18  riastrad 		INIT_LIST_HEAD(list);
    200  1.18  riastrad 	}
    201  1.18  riastrad }
    202  1.18  riastrad 
    203  1.18  riastrad static inline void
    204   1.1     skrll list_splice_tail(const struct list_head *list, struct list_head *head)
    205   1.1     skrll {
    206   1.1     skrll 	if (!list_empty(list))
    207   1.1     skrll 		__list_splice_between(head->prev, list, head);
    208   1.1     skrll }
    209   1.1     skrll 
    210   1.1     skrll static inline void
    211  1.15  riastrad list_splice_tail_init(struct list_head *list, struct list_head *head)
    212  1.15  riastrad {
    213  1.15  riastrad 	if (!list_empty(list)) {
    214  1.15  riastrad 		__list_splice_between(head->prev, list, head);
    215  1.15  riastrad 		INIT_LIST_HEAD(list);
    216  1.15  riastrad 	}
    217  1.15  riastrad }
    218  1.15  riastrad 
    219  1.15  riastrad static inline void
    220   1.1     skrll list_move(struct list_head *node, struct list_head *head)
    221   1.1     skrll {
    222   1.1     skrll 	list_del(node);
    223   1.1     skrll 	list_add(node, head);
    224   1.1     skrll }
    225   1.1     skrll 
    226   1.1     skrll static inline void
    227   1.1     skrll list_move_tail(struct list_head *node, struct list_head *head)
    228   1.1     skrll {
    229   1.1     skrll 	list_del(node);
    230   1.1     skrll 	list_add_tail(node, head);
    231   1.1     skrll }
    232   1.1     skrll 
    233   1.1     skrll static inline void
    234  1.26  riastrad list_bulk_move_tail(struct list_head *head, struct list_head *first,
    235  1.26  riastrad     struct list_head *last)
    236  1.26  riastrad {
    237  1.26  riastrad 
    238  1.26  riastrad 	first->prev->next = last->next;
    239  1.26  riastrad 	last->next->prev = first->prev;
    240  1.26  riastrad 
    241  1.26  riastrad 	head->prev->next = first;
    242  1.26  riastrad 	first->prev = head->prev;
    243  1.26  riastrad 
    244  1.26  riastrad 	last->next = head;
    245  1.26  riastrad 	head->prev = last;
    246  1.26  riastrad }
    247  1.26  riastrad 
    248  1.26  riastrad static inline void
    249   1.1     skrll list_replace(struct list_head *old, struct list_head *new)
    250   1.1     skrll {
    251   1.1     skrll 	new->prev = old->prev;
    252   1.1     skrll 	old->prev->next = new;
    253   1.1     skrll 	new->next = old->next;
    254   1.1     skrll 	old->next->prev = new;
    255   1.1     skrll }
    256   1.1     skrll 
    257   1.1     skrll static inline void
    258  1.14  riastrad list_replace_init(struct list_head *old, struct list_head *new)
    259  1.14  riastrad {
    260  1.14  riastrad 	list_replace(old, new);
    261  1.14  riastrad 	INIT_LIST_HEAD(old);
    262  1.14  riastrad }
    263  1.14  riastrad 
    264  1.14  riastrad static inline void
    265   1.1     skrll list_del_init(struct list_head *node)
    266   1.1     skrll {
    267   1.1     skrll 	list_del(node);
    268   1.1     skrll 	INIT_LIST_HEAD(node);
    269   1.1     skrll }
    270   1.1     skrll 
    271   1.1     skrll #define	list_entry(PTR, TYPE, FIELD)	container_of(PTR, TYPE, FIELD)
    272   1.1     skrll #define	list_first_entry(PTR, TYPE, FIELD)				\
    273   1.1     skrll 	list_entry(list_first((PTR)), TYPE, FIELD)
    274  1.10  riastrad #define	list_first_entry_or_null(PTR, TYPE, FIELD)			\
    275  1.10  riastrad 	(list_empty((PTR)) ? NULL : list_entry(list_first((PTR)), TYPE, FIELD))
    276   1.5  riastrad #define	list_last_entry(PTR, TYPE, FIELD)				\
    277   1.5  riastrad 	list_entry(list_last((PTR)), TYPE, FIELD)
    278   1.3  riastrad #define	list_next_entry(ENTRY, FIELD)					\
    279   1.3  riastrad 	list_entry(list_next(&(ENTRY)->FIELD), typeof(*(ENTRY)), FIELD)
    280   1.5  riastrad #define	list_prev_entry(ENTRY, FIELD)					\
    281   1.5  riastrad 	list_entry(list_prev(&(ENTRY)->FIELD), typeof(*(ENTRY)), FIELD)
    282   1.1     skrll 
    283   1.1     skrll #define	list_for_each(VAR, HEAD)					\
    284   1.1     skrll 	for ((VAR) = list_first((HEAD));				\
    285   1.1     skrll 		(VAR) != (HEAD);					\
    286   1.1     skrll 		(VAR) = list_next((VAR)))
    287   1.1     skrll 
    288  1.31  riastrad #define	list_for_each_prev(VAR, HEAD)					\
    289  1.31  riastrad 	for ((VAR) = list_last((HEAD));					\
    290  1.31  riastrad 		(VAR) != (HEAD);					\
    291  1.31  riastrad 		(VAR) = list_prev((VAR)))
    292  1.31  riastrad 
    293   1.1     skrll #define	list_for_each_safe(VAR, NEXT, HEAD)				\
    294   1.1     skrll 	for ((VAR) = list_first((HEAD));				\
    295   1.1     skrll 		((VAR) != (HEAD)) && ((NEXT) = list_next((VAR)), 1);	\
    296   1.1     skrll 		(VAR) = (NEXT))
    297   1.1     skrll 
    298  1.29  riastrad #define	list_safe_reset_next(VAR, NEXT, FIELD)				\
    299  1.29  riastrad 	(NEXT) = list_next_entry(VAR, FIELD)
    300  1.29  riastrad 
    301   1.1     skrll #define	list_for_each_entry(VAR, HEAD, FIELD)				\
    302   1.1     skrll 	for ((VAR) = list_entry(list_first((HEAD)), typeof(*(VAR)), FIELD); \
    303   1.1     skrll 		&(VAR)->FIELD != (HEAD);				\
    304   1.1     skrll 		(VAR) = list_entry(list_next(&(VAR)->FIELD), typeof(*(VAR)), \
    305   1.1     skrll 		    FIELD))
    306   1.1     skrll 
    307   1.1     skrll #define	list_for_each_entry_safe(VAR, NEXT, HEAD, FIELD)		\
    308   1.1     skrll 	for ((VAR) = list_entry(list_first((HEAD)), typeof(*(VAR)), FIELD); \
    309   1.1     skrll 		(&(VAR)->FIELD != (HEAD)) &&				\
    310   1.1     skrll 		    ((NEXT) = list_entry(list_next(&(VAR)->FIELD),	\
    311   1.1     skrll 			typeof(*(VAR)), FIELD), 1);			\
    312   1.1     skrll 		(VAR) = (NEXT))
    313   1.1     skrll 
    314  1.28  riastrad #define	list_for_each_entry_safe_reverse(VAR, NEXT, HEAD, FIELD)	\
    315  1.28  riastrad 	for ((VAR) = list_entry(list_last((HEAD)), typeof(*(VAR)), FIELD); \
    316  1.28  riastrad 		(&(VAR)->FIELD != (HEAD)) &&				\
    317  1.28  riastrad 		    ((NEXT) = list_entry(list_prev(&(VAR)->FIELD),	\
    318  1.28  riastrad 		        typeof(*(VAR)), FIELD), 1);			\
    319  1.28  riastrad 		(VAR) = (NEXT))
    320  1.28  riastrad 
    321  1.28  riastrad #define	list_for_each_entry_reverse(VAR, HEAD, FIELD)			\
    322  1.28  riastrad 	for ((VAR) = list_entry(list_last((HEAD)), typeof(*(VAR)), FIELD); \
    323  1.28  riastrad 		&(VAR)->FIELD != (HEAD);				\
    324  1.28  riastrad 		(VAR) = list_entry(list_prev(&(VAR)->FIELD), typeof(*(VAR)), \
    325  1.28  riastrad 		    FIELD))
    326  1.28  riastrad 
    327   1.3  riastrad #define	list_for_each_entry_continue(VAR, HEAD, FIELD)			\
    328   1.3  riastrad 	for ((VAR) = list_next_entry((VAR), FIELD);			\
    329   1.3  riastrad 		&(VAR)->FIELD != (HEAD);				\
    330   1.3  riastrad 		(VAR) = list_next_entry((VAR), FIELD))
    331   1.3  riastrad 
    332   1.5  riastrad #define	list_for_each_entry_continue_reverse(VAR, HEAD, FIELD)		\
    333   1.5  riastrad 	for ((VAR) = list_prev_entry((VAR), FIELD);			\
    334   1.5  riastrad 		&(VAR)->FIELD != (HEAD);				\
    335   1.5  riastrad 		(VAR) = list_prev_entry((VAR), FIELD))
    336   1.5  riastrad 
    337  1.24  riastrad #define	list_for_each_entry_from(VAR, HEAD, FIELD)			\
    338  1.24  riastrad 	for (;								\
    339  1.24  riastrad 		(&(VAR)->FIELD != (HEAD));				\
    340  1.24  riastrad 		(VAR) = list_next_entry((VAR), FIELD))
    341  1.24  riastrad 
    342  1.27  riastrad #define	list_for_each_entry_from_reverse(VAR, HEAD, FIELD)		\
    343  1.27  riastrad 	for (;								\
    344  1.27  riastrad 		(&(VAR)->FIELD != (HEAD));				\
    345  1.27  riastrad 		(VAR) = list_prev_entry((VAR), FIELD))
    346  1.27  riastrad 
    347   1.4  riastrad #define	list_for_each_entry_safe_from(VAR, NEXT, HEAD, FIELD)		\
    348   1.4  riastrad 	for (;								\
    349   1.4  riastrad 		(&(VAR)->FIELD != (HEAD)) &&				\
    350   1.4  riastrad 		    ((NEXT) = list_next_entry((VAR), FIELD));		\
    351   1.4  riastrad 		(VAR) = (NEXT))
    352   1.4  riastrad 
    353   1.1     skrll /*
    354   1.1     skrll  * `H'ead-only/`H'ash-table doubly-linked lists.
    355   1.1     skrll  */
    356   1.1     skrll 
    357   1.7  riastrad #define	hlist_head	pslist_head
    358   1.7  riastrad #define	hlist_node	pslist_entry
    359   1.1     skrll 
    360   1.7  riastrad #define	HLIST_HEAD_INIT	PSLIST_INITIALIZER
    361   1.7  riastrad #define	INIT_HLIST_HEAD	PSLIST_INIT
    362   1.7  riastrad #define	hlist_empty(h)	(pslist_writer_first(h) == NULL)
    363   1.7  riastrad #define	hlist_first	pslist_writer_first
    364   1.7  riastrad #define	hlist_next	pslist_writer_next
    365  1.17  riastrad 
    366  1.17  riastrad static inline void
    367  1.17  riastrad hlist_add_head(struct hlist_node *node, struct hlist_head *head)
    368  1.17  riastrad {
    369  1.17  riastrad 
    370  1.17  riastrad 	pslist_entry_init(node);
    371  1.17  riastrad 	pslist_writer_insert_head(head, node);
    372  1.17  riastrad }
    373   1.6  riastrad 
    374   1.6  riastrad static inline void
    375   1.7  riastrad hlist_del(struct hlist_node *node)
    376   1.6  riastrad {
    377   1.6  riastrad 
    378   1.7  riastrad 	pslist_writer_remove(node);
    379   1.7  riastrad 	/* XXX abstraction violation */
    380   1.7  riastrad 	node->ple_prevp = _PSLIST_POISON;
    381   1.1     skrll }
    382   1.1     skrll 
    383   1.1     skrll static inline void
    384   1.7  riastrad hlist_del_init(struct hlist_node *node)
    385   1.1     skrll {
    386   1.1     skrll 
    387   1.7  riastrad 	/* XXX abstraction violation */
    388   1.7  riastrad 	if (node->ple_prevp != NULL)
    389   1.7  riastrad 		pslist_writer_remove(node);
    390   1.1     skrll }
    391   1.1     skrll 
    392   1.1     skrll #define	hlist_entry(PTR, TYPE, FIELD)	container_of(PTR, TYPE, FIELD)
    393   1.7  riastrad #define	hlist_for_each(VAR, HEAD)					      \
    394   1.7  riastrad 	for ((VAR) = hlist_first(HEAD); (VAR) != NULL; (VAR) = hlist_next(VAR))
    395   1.7  riastrad #define	hlist_for_each_safe(VAR, NEXT, HEAD)				      \
    396  1.16  riastrad 	for ((VAR) = hlist_first(HEAD);					      \
    397  1.16  riastrad 		(VAR) != NULL && ((NEXT) = hlist_next(HEAD), 1);	      \
    398   1.7  riastrad 		(VAR) = (NEXT))
    399   1.7  riastrad #define	hlist_for_each_entry(VAR, HEAD, FIELD)				      \
    400   1.7  riastrad 	for ((VAR) = (hlist_first(HEAD) == NULL ? NULL :		      \
    401   1.7  riastrad 			hlist_entry(hlist_first(HEAD), typeof(*(VAR)),	      \
    402   1.7  riastrad 			    FIELD));					      \
    403   1.7  riastrad 		(VAR) != NULL;						      \
    404   1.9  riastrad 		(VAR) = (hlist_next(&(VAR)->FIELD) == NULL ? NULL :	      \
    405   1.8  riastrad 			hlist_entry(hlist_next(&(VAR)->FIELD), typeof(*(VAR)),\
    406   1.8  riastrad 			    FIELD)))
    407   1.1     skrll 
    408   1.6  riastrad #define	hlist_for_each_entry_safe(VAR, NEXT, HEAD, FIELD)		      \
    409   1.7  riastrad 	for ((VAR) = (hlist_first(HEAD) == NULL ? NULL :		      \
    410   1.7  riastrad 			hlist_entry(hlist_first(HEAD), typeof(*(VAR)),	      \
    411  1.16  riastrad 			    FIELD));					      \
    412  1.16  riastrad 		((VAR) != NULL &&					      \
    413  1.16  riastrad 		    ((NEXT) = hlist_next(&(VAR)->FIELD), 1));		      \
    414  1.16  riastrad 	        (VAR) = hlist_entry((NEXT), typeof(*(VAR)), FIELD))
    415   1.6  riastrad 
    416  1.17  riastrad static inline void
    417  1.17  riastrad hlist_add_behind_rcu(struct hlist_node *node, struct hlist_node *prev)
    418  1.17  riastrad {
    419  1.17  riastrad 
    420  1.17  riastrad 	pslist_entry_init(node);
    421  1.17  riastrad 	pslist_writer_insert_after(prev, node);
    422  1.17  riastrad }
    423  1.17  riastrad 
    424  1.17  riastrad static inline void
    425  1.17  riastrad hlist_add_head_rcu(struct hlist_node *node, struct hlist_head *head)
    426  1.17  riastrad {
    427  1.17  riastrad 
    428  1.17  riastrad 	pslist_entry_init(node);
    429  1.17  riastrad 	pslist_writer_insert_head(head, node);
    430  1.17  riastrad }
    431  1.17  riastrad 
    432  1.17  riastrad #define	hlist_del_init_rcu	hlist_del_init /* no special needs */
    433   1.7  riastrad 
    434   1.7  riastrad #define	hlist_first_rcu		pslist_reader_first
    435   1.7  riastrad #define	hlist_next_rcu		pslist_reader_next
    436   1.7  riastrad 
    437   1.7  riastrad #define	hlist_for_each_entry_rcu(VAR, HEAD, FIELD)			      \
    438   1.7  riastrad 	for ((VAR) = (hlist_first_rcu(HEAD) == NULL ? NULL :		      \
    439   1.7  riastrad 			hlist_entry(hlist_first_rcu(HEAD), typeof(*(VAR)),    \
    440   1.7  riastrad 			    FIELD));					      \
    441   1.7  riastrad 		(VAR) != NULL;						      \
    442  1.11  riastrad 		(VAR) = (hlist_next_rcu(&(VAR)->FIELD) == NULL ? NULL :	      \
    443  1.11  riastrad 			hlist_entry(hlist_next_rcu(&(VAR)->FIELD),	      \
    444  1.11  riastrad 			    typeof(*(VAR)), FIELD)))
    445   1.1     skrll 
    446   1.1     skrll #endif  /* _LINUX_LIST_H_ */
    447