1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright (C) 2018 Intel Corporation.
3 * All rights reserved.
4 */
5
6 #ifndef __OCF_LIST_H__
7 #define __OCF_LIST_H__
8
9 #define LIST_POISON1 ((void *) 0x00100100)
10 #define LIST_POISON2 ((void *) 0x00200200)
11
12 /**
13 * List entry structure mimicking linux kernel based one.
14 */
15 struct list_head {
16 struct list_head *next;
17 struct list_head *prev;
18 } __attribute__((aligned(64)));
19
20 /**
21 * start an empty list
22 */
23 #define INIT_LIST_HEAD(l) { (l)->prev = l; (l)->next = l; }
24
25 /**
26 * Add item to list head.
27 * @param it list entry to be added
28 * @param l1 list main node (head)
29 */
30 static inline void
list_add(struct list_head * it,struct list_head * l1)31 list_add(struct list_head *it, struct list_head *l1)
32 {
33 it->prev = l1;
34 it->next = l1->next;
35
36 l1->next->prev = it;
37 l1->next = it;
38 }
39
40 /**
41 * Add item it to tail.
42 * @param it list entry to be added
43 * @param l1 list main node (head)
44 */
45 static inline void
list_add_tail(struct list_head * it,struct list_head * l1)46 list_add_tail(struct list_head *it, struct list_head *l1)
47 {
48 it->prev = l1->prev;
49 it->next = l1;
50
51 l1->prev->next = it;
52 l1->prev = it;
53 }
54
55 /**
56 * check if a list is empty (return true)
57 */
58 static inline int
list_empty(struct list_head * it)59 list_empty(struct list_head *it)
60 {
61 return it->next == it;
62 }
63
64 /**
65 * delete an entry from a list
66 */
67 static inline void
list_del(struct list_head * it)68 list_del(struct list_head *it)
69 {
70 it->next->prev = it->prev;
71 it->prev->next = it->next;
72 }
73
74 static inline void
list_move_tail(struct list_head * list,struct list_head * head)75 list_move_tail(struct list_head *list,
76 struct list_head *head)
77 {
78 list_del(list);
79 list_add_tail(list, head);
80 }
81
82 static inline void
list_move(struct list_head * list,struct list_head * head)83 list_move(struct list_head *list,
84 struct list_head *head)
85 {
86 list_del(list);
87 list_add(list, head);
88 }
89
90 /**
91 * Extract an entry.
92 * @param list_head_i list head item, from which entry is extracted
93 * @param item_type type (struct) of list entry
94 * @param field_name name of list_head field within item_type
95 */
96 #define list_entry(list_head_i, item_type, field_name) \
97 (item_type *)(((void*)(list_head_i)) - offsetof(item_type, field_name))
98
99 #define list_first_entry(list_head_i, item_type, field_name) \
100 list_entry((list_head_i)->next, item_type, field_name)
101
102 /**
103 * @param iterator uninitialized list_head pointer, to be used as iterator
104 * @param plist list head (main node)
105 */
106 #define list_for_each(iterator, plist) \
107 for (iterator = (plist)->next; \
108 (iterator)->next != (plist)->next; \
109 iterator = (iterator)->next)
110
111 /**
112 * Safe version of list_for_each which works even if entries are deleted during
113 * loop.
114 * @param iterator uninitialized list_head pointer, to be used as iterator
115 * @param q another uninitialized list_head, used as helper
116 * @param plist list head (main node)
117 */
118 /*
119 * Algorithm handles situation, where q is deleted.
120 * consider in example 3 element list with header h:
121 *
122 * h -> 1 -> 2 -> 3 ->
123 *1. i q
124 *
125 *2. i q
126 *
127 *3. q i
128 */
129 #define list_for_each_safe(iterator, q, plist) \
130 for (iterator = (q = (plist)->next->next)->prev; \
131 (q) != (plist)->next; \
132 iterator = (q = (q)->next)->prev)
133
134 #define _list_entry_helper(item, head, field_name) list_entry(head, typeof(*item), field_name)
135
136 /**
137 * Iterate over list entries.
138 * @param list pointer to list item (iterator)
139 * @param plist pointer to list_head item
140 * @param field_name name of list_head field in list entry
141 */
142 #define list_for_each_entry(item, plist, field_name) \
143 for (item = _list_entry_helper(item, (plist)->next, field_name); \
144 _list_entry_helper(item, (item)->field_name.next, field_name) !=\
145 _list_entry_helper(item, (plist)->next, field_name); \
146 item = _list_entry_helper(item, (item)->field_name.next, field_name))
147
148 /**
149 * Safe version of list_for_each_entry which works even if entries are deleted
150 * during loop.
151 * @param list pointer to list item (iterator)
152 * @param q another pointer to list item, used as helper
153 * @param plist pointer to list_head item
154 * @param field_name name of list_head field in list entry
155 */
156 #define list_for_each_entry_safe(item, q, plist, field_name) \
157 for (item = _list_entry_helper(item, (plist)->next, field_name), \
158 q = _list_entry_helper(item, (item)->field_name.next, field_name); \
159 _list_entry_helper(item, (item)->field_name.next, field_name) != \
160 _list_entry_helper(item, (plist)->next, field_name); \
161 item = q, q = _list_entry_helper(q, (q)->field_name.next, field_name))
162
163 #endif
164