summaryrefslogtreecommitdiffstats
path: root/sys/ofed/include/linux/list.h
diff options
context:
space:
mode:
Diffstat (limited to 'sys/ofed/include/linux/list.h')
-rw-r--r--sys/ofed/include/linux/list.h70
1 files changed, 66 insertions, 4 deletions
diff --git a/sys/ofed/include/linux/list.h b/sys/ofed/include/linux/list.h
index 4b5454a..a3becab 100644
--- a/sys/ofed/include/linux/list.h
+++ b/sys/ofed/include/linux/list.h
@@ -2,6 +2,7 @@
* Copyright (c) 2010 Isilon Systems, Inc.
* Copyright (c) 2010 iX Systems, Inc.
* Copyright (c) 2010 Panasas, Inc.
+ * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -307,6 +308,66 @@ hlist_move_list(struct hlist_head *old, struct hlist_head *new)
new->first->pprev = &new->first;
old->first = NULL;
}
+
+/**
+ * list_is_singular - tests whether a list has just one entry.
+ * @head: the list to test.
+ */
+static inline int list_is_singular(const struct list_head *head)
+{
+ return !list_empty(head) && (head->next == head->prev);
+}
+
+static inline void __list_cut_position(struct list_head *list,
+ struct list_head *head, struct list_head *entry)
+{
+ struct list_head *new_first = entry->next;
+ list->next = head->next;
+ list->next->prev = list;
+ list->prev = entry;
+ entry->next = list;
+ head->next = new_first;
+ new_first->prev = head;
+}
+
+/**
+ * list_cut_position - cut a list into two
+ * @list: a new list to add all removed entries
+ * @head: a list with entries
+ * @entry: an entry within head, could be the head itself
+ * and if so we won't cut the list
+ *
+ * This helper moves the initial part of @head, up to and
+ * including @entry, from @head to @list. You should
+ * pass on @entry an element you know is on @head. @list
+ * should be an empty list or a list you do not care about
+ * losing its data.
+ *
+ */
+static inline void list_cut_position(struct list_head *list,
+ struct list_head *head, struct list_head *entry)
+{
+ if (list_empty(head))
+ return;
+ if (list_is_singular(head) &&
+ (head->next != entry && head != entry))
+ return;
+ if (entry == head)
+ INIT_LIST_HEAD(list);
+ else
+ __list_cut_position(list, head, entry);
+}
+
+/**
+ * list_is_last - tests whether @list is the last entry in list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static inline int list_is_last(const struct list_head *list,
+ const struct list_head *head)
+{
+ return list->next == head;
+}
#define hlist_entry(ptr, type, field) container_of(ptr, type, field)
@@ -327,9 +388,10 @@ hlist_move_list(struct hlist_head *old, struct hlist_head *new)
#define hlist_for_each_entry_from(tp, p, field) \
for (; p ? (tp = hlist_entry(p, typeof(*tp), field)): NULL; p = p->next)
-#define hlist_for_each_entry_safe(tp, p, n, head, field) \
- for (p = (head)->first; p ? \
- (n = p->next) | (tp = hlist_entry(p, typeof(*tp), field)) : \
- NULL; p = n)
+#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
+ for (pos = (head)->first; \
+ (pos) != 0 && ({ n = (pos)->next; \
+ tpos = hlist_entry((pos), typeof(*(tpos)), member); 1;}); \
+ pos = (n))
#endif /* _LINUX_LIST_H_ */
OpenPOWER on IntegriCloud