--- /dev/null
+#ifndef _KCOMPAT_HLIST_H
+#define _KCOMPAT_HLIST_H
+
+/*
+ * Kernel sourcecode compatible lightweight single pointer list head useful
+ * for implementing hash tables
+ *
+ * Copyright (C) 2009 Novell Inc.
+ *
+ * Author: Jan Blunck <jblunck@suse.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ */
+
+struct hlist_head
+{
+ struct hlist_node *next;
+};
+
+struct hlist_node
+{
+ struct hlist_node *next;
+ struct hlist_node *prev;
+};
+
+/* Initialize a new list head. */
+static inline void INIT_HLIST_HEAD(struct hlist_head *ptr)
+{
+ ptr->next = NULL;
+}
+
+/* Get typed element from list at a given position. */
+#define hlist_entry(ptr, type, member) \
+ ((type *) ((char *) (ptr) - (unsigned long) (&((type *) 0)->member)))
+
+/* Add new element at the head of the list. */
+static inline void hlist_add_head (struct hlist_node *newp,
+ struct hlist_head *head)
+{
+ if (head->next)
+ head->next->prev = newp;
+
+ newp->next = head->next;
+ newp->prev = (struct hlist_node *)head;
+ head->next = newp;
+}
+
+/* Remove element from list. */
+static inline void hlist_del (struct hlist_node *elem)
+{
+ if (elem->next)
+ elem->next->prev = elem->prev;
+
+ elem->prev->next = elem->next;
+}
+
+#define hlist_for_each_entry(entry, pos, head, member) \
+ for (pos = (head)->next, \
+ entry = hlist_entry(pos, typeof(*entry), member); \
+ pos != NULL; \
+ pos = pos->next, \
+ entry = hlist_entry(pos, typeof(*entry), member))
+
+#define hlist_for_each_entry_safe(entry, pos, p, head, member) \
+ for (pos = (head)->next, \
+ entry = hlist_entry(pos, typeof(*entry), member); \
+ (pos != NULL) && ({ p = pos->next; 1;}); \
+ pos = p, \
+ entry = hlist_entry(pos, typeof(*entry), member))
+
+#endif /* _KCOMPAT_HLIST_H */
-#ifndef _KCOMPAT_RCULIST_H
-#define _KCOMPAT_RCULIST_H
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
-/*
- * RCU-protected list version
- *
- * 2002-10-18 19:01:25-07:00, dipankar@in.ibm.com
- * [PATCH] RCU helper patchset 2/2
- *
- * This adds a set of list macros that make handling of list protected
- * by RCU simpler. The interfaces added are -
- *
- * list_add_rcu
- * list_add_tail_rcu
- * - Adds an element by taking care of memory barrier (wmb()).
- *
- * list_del_rcu
- * - Deletes an element but doesn't re-initialize the pointers in
- * the element for supporting RCU based traversal.
- *
- * list_for_each_rcu
- * __list_for_each_rcu
- * - Traversal of RCU protected list - takes care of memory barriers
- * transparently.
- *
- */
+ Copyright (C) 2009 Pierre-Marc Fournier
+ Conversion to RCU list.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
-#define _LGPL_SOURCE
+#ifndef _URCU_RCULIST_H
+#define _URCU_RCULIST_H
+
+#include <urcu/list.h>
#include <urcu.h>
-#include <kcompat/list.h>
-/*
- * Insert a new entry between two known consecutive entries.
- *
- * This is only for internal list manipulation where we know
- * the prev/next entries already!
+/* Add new element at the head of the list.
*/
-static __inline__ void __list_add_rcu(struct list_head * new,
- struct list_head * prev,
- struct list_head * next)
+static inline void list_add_rcu(list_t *newp, list_t *head)
{
- new->next = next;
- new->prev = prev;
+ newp->next = head->next;
+ newp->prev = head;
smp_wmb();
- next->prev = new;
- prev->next = new;
+ head->next->prev = newp;
+ head->next = newp;
}
-/**
- * list_add_rcu - add a new entry to rcu-protected list
- * @new: new entry to be added
- * @head: list head to add it after
- *
- * Insert a new entry after the specified head.
- * This is good for implementing stacks.
- *
- * The caller must take whatever precautions are necessary
- * (such as holding appropriate locks) to avoid racing
- * with another list-mutation primitive, such as list_add_rcu()
- * or list_del_rcu(), running on this same list.
- * However, it is perfectly legal to run concurrently with
- * the _rcu list-traversal primitives, such as
- * list_for_each_entry_rcu().
- */
-static __inline__ void list_add_rcu(struct list_head *new,
- struct list_head *head)
-{
- __list_add_rcu(new, head, head->next);
-}
-/**
- * list_add_tail_rcu - add a new entry to rcu-protected list
- * @new: new entry to be added
- * @head: list head to add it before
- *
- * Insert a new entry before the specified head.
- * This is useful for implementing queues.
- *
- * The caller must take whatever precautions are necessary
- * (such as holding appropriate locks) to avoid racing
- * with another list-mutation primitive, such as list_add_tail_rcu()
- * or list_del_rcu(), running on this same list.
- * However, it is perfectly legal to run concurrently with
- * the _rcu list-traversal primitives, such as
- * list_for_each_entry_rcu().
- */
-static __inline__ void list_add_tail_rcu(struct list_head *new,
- struct list_head *head)
+/* Remove element from list. */
+static inline void list_del_rcu(list_t *elem)
{
- __list_add_rcu(new, head->prev, head);
+ elem->next->prev = elem->prev;
+ elem->prev->next = elem->next;
}
-/**
- * list_del_rcu - deletes entry from list without re-initialization
- * @entry: the element to delete from the list.
- *
- * Note: list_empty on entry does not return true after this,
- * the entry is in an undefined state. It is useful for RCU based
- * lockfree traversal.
- *
- * The caller must take whatever precautions are necessary
- * (such as holding appropriate locks) to avoid racing
- * with another list-mutation primitive, such as list_del_rcu()
- * or list_add_rcu(), running on this same list.
- * However, it is perfectly legal to run concurrently with
- * the _rcu list-traversal primitives, such as
- * list_for_each_entry_rcu().
- *
- * Note that the caller is not permitted to immediately free
- * the newly deleted entry. Instead, either synchronize_kernel()
- * or call_rcu() must be used to defer freeing until an RCU
- * grace period has elapsed.
- */
-static inline void list_del_rcu(struct list_head *entry)
-{
- __list_del(entry->prev, entry->next);
-}
-/**
- * list_for_each_rcu - iterate over an rcu-protected list
- * @pos: the &struct list_head to use as a loop counter.
- * @head: the head for your list.
- *
- * This list-traversal primitive may safely run concurrently with
- * the _rcu list-mutation primitives such as list_add_rcu()
- * as long as the traversal is guarded by rcu_read_lock().
+/* Iterate through elements of the list.
+ * This must be done while rcu_read_lock() is held.
*/
-#define list_for_each_rcu(pos, head) \
- for (pos = rcu_dereference((head)->next); \
- prefetch(pos->next), pos != (head); \
- pos = rcu_dereference(pos->next))
-
-#define __list_for_each_rcu(pos, head) \
- for (pos = rcu_dereference((head)->next); \
- pos != (head); \
- pos = rcu_dereference(pos->next))
-/**
- * list_for_each_entry_rcu - iterate over a rcu-protected list
- * @pos: the struct type pointer to use as a loop counter
- * @head: the head for your list
- * @member: the name of the struct list_head element in your struct type
- *
- * This list-traversal primitive may safely run concurrently with
- * the _rcu list-mutation primitives such as list_add_rcu()
- * as long as the traversal is guarded by rcu_read_lock().
- */
-#define list_for_each_entry_rcu(pos, head, member) \
- for (pos = list_entry(rcu_dereference((head)->next), typeof(*pos), \
- member); \
- prefetch(pos->member.next), &pos->member != (head); \
- pos = list_entry(rcu_dereference(pos->member.next),typeof(*pos), \
- member))
+#define list_for_each_entry_rcu(pos, head, member) \
+ for (pos = list_entry(rcu_dereference((head)->next), typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(rcu_dereference(pos->member.next), typeof(*pos), member))
-#endif /* _KCOMPAT_RCULIST_H */
+#endif /* _URCU_RCULIST_H */