aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds/xlist.h
diff options
context:
space:
mode:
Diffstat (limited to 'net/rds/xlist.h')
-rw-r--r--net/rds/xlist.h54
1 files changed, 12 insertions, 42 deletions
diff --git a/net/rds/xlist.h b/net/rds/xlist.h
index 8c21aca49d50..e6b5190daddd 100644
--- a/net/rds/xlist.h
+++ b/net/rds/xlist.h
@@ -10,13 +10,18 @@ struct xlist_head {
10 struct xlist_head *next; 10 struct xlist_head *next;
11}; 11};
12 12
13/* 13static inline void INIT_XLIST_HEAD(struct xlist_head *list)
14 * XLIST_PTR_TAIL can be used to prevent double insertion. See 14{
15 * xlist_protect() 15 list->next = NULL;
16 */ 16}
17#define XLIST_PTR_TAIL ((struct xlist_head *)0x1) 17
18static inline int xlist_empty(struct xlist_head *head)
19{
20 return head->next == NULL;
21}
18 22
19static inline void xlist_add(struct xlist_head *new, struct xlist_head *tail, struct xlist_head *head) 23static inline void xlist_add(struct xlist_head *new, struct xlist_head *tail,
24 struct xlist_head *head)
20{ 25{
21 struct xlist_head *cur; 26 struct xlist_head *cur;
22 struct xlist_head *check; 27 struct xlist_head *check;
@@ -30,26 +35,6 @@ static inline void xlist_add(struct xlist_head *new, struct xlist_head *tail, st
30 } 35 }
31} 36}
32 37
33/*
34 * To avoid duplicate insertion by two CPUs of the same xlist item
35 * you can call xlist_protect. It will stuff XLIST_PTR_TAIL
36 * into the entry->next pointer with xchg, and only return 1
37 * if there was a NULL there before.
38 *
39 * if xlist_protect returns zero, someone else is busy working
40 * on this entry. Getting a NULL into the entry in a race
41 * free manner is the caller's job.
42 */
43static inline int xlist_protect(struct xlist_head *entry)
44{
45 struct xlist_head *val;
46
47 val = xchg(&entry->next, XLIST_PTR_TAIL);
48 if (val == NULL)
49 return 1;
50 return 0;
51}
52
53static inline struct xlist_head *xlist_del_head(struct xlist_head *head) 38static inline struct xlist_head *xlist_del_head(struct xlist_head *head)
54{ 39{
55 struct xlist_head *cur; 40 struct xlist_head *cur;
@@ -61,11 +46,6 @@ static inline struct xlist_head *xlist_del_head(struct xlist_head *head)
61 if (!cur) 46 if (!cur)
62 goto out; 47 goto out;
63 48
64 if (cur == XLIST_PTR_TAIL) {
65 cur = NULL;
66 goto out;
67 }
68
69 next = cur->next; 49 next = cur->next;
70 check = cmpxchg(&head->next, cur, next); 50 check = cmpxchg(&head->next, cur, next);
71 if (check == cur) 51 if (check == cur)
@@ -80,7 +60,7 @@ static inline struct xlist_head *xlist_del_head_fast(struct xlist_head *head)
80 struct xlist_head *cur; 60 struct xlist_head *cur;
81 61
82 cur = head->next; 62 cur = head->next;
83 if (!cur || cur == XLIST_PTR_TAIL) 63 if (!cur)
84 return NULL; 64 return NULL;
85 65
86 head->next = cur->next; 66 head->next = cur->next;
@@ -97,14 +77,4 @@ static inline void xlist_splice(struct xlist_head *list,
97 head->next = cur; 77 head->next = cur;
98} 78}
99 79
100static inline void INIT_XLIST_HEAD(struct xlist_head *list)
101{
102 list->next = NULL;
103}
104
105static inline int xlist_empty(struct xlist_head *head)
106{
107 return head->next == NULL || head->next == XLIST_PTR_TAIL;
108}
109
110#endif 80#endif