]> git.ipfire.org Git - thirdparty/util-linux.git/blob - include/list.h
Merge branch 'travis-checkusage' of https://github.com/rudimeier/util-linux
[thirdparty/util-linux.git] / include / list.h
1 /*
2 * Copyright (C) 2008 Karel Zak <kzak@redhat.com>
3 * Copyright (C) 1999-2008 by Theodore Ts'o
4 *
5 * This file may be redistributed under the terms of the
6 * GNU Lesser General Public License.
7 *
8 * (based on list.h from e2fsprogs)
9 * Merge sort based on kernel's implementation.
10 */
11
12 #ifndef UTIL_LINUX_LIST_H
13 #define UTIL_LINUX_LIST_H
14
15 /* TODO: use AC_C_INLINE */
16 #ifdef __GNUC__
17 #define _INLINE_ static __inline__
18 #else /* For Watcom C */
19 #define _INLINE_ static inline
20 #endif
21
22 /*
23 * Simple doubly linked list implementation.
24 *
25 * Some of the internal functions ("__xxx") are useful when
26 * manipulating whole lists rather than single entries, as
27 * sometimes we already know the next/prev entries and we can
28 * generate better code by using them directly rather than
29 * using the generic single-entry routines.
30 */
31
32 struct list_head {
33 struct list_head *next, *prev;
34 };
35
36 #define INIT_LIST_HEAD(ptr) do { \
37 (ptr)->next = (ptr); (ptr)->prev = (ptr); \
38 } while (0)
39
40 /*
41 * Insert a new entry between two known consecutive entries.
42 *
43 * This is only for internal list manipulation where we know
44 * the prev/next entries already!
45 */
46 _INLINE_ void __list_add(struct list_head * add,
47 struct list_head * prev,
48 struct list_head * next)
49 {
50 next->prev = add;
51 add->next = next;
52 add->prev = prev;
53 prev->next = add;
54 }
55
56 /**
57 * list_add - add a new entry
58 * @add: new entry to be added
59 * @head: list head to add it after
60 *
61 * Insert a new entry after the specified head.
62 * This is good for implementing stacks.
63 */
64 _INLINE_ void list_add(struct list_head *add, struct list_head *head)
65 {
66 __list_add(add, head, head->next);
67 }
68
69 /**
70 * list_add_tail - add a new entry
71 * @add: new entry to be added
72 * @head: list head to add it before
73 *
74 * Insert a new entry before the specified head.
75 * This is useful for implementing queues.
76 */
77 _INLINE_ void list_add_tail(struct list_head *add, struct list_head *head)
78 {
79 __list_add(add, head->prev, head);
80 }
81
82 /*
83 * Delete a list entry by making the prev/next entries
84 * point to each other.
85 *
86 * This is only for internal list manipulation where we know
87 * the prev/next entries already!
88 */
89 _INLINE_ void __list_del(struct list_head * prev,
90 struct list_head * next)
91 {
92 next->prev = prev;
93 prev->next = next;
94 }
95
96 /**
97 * list_del - deletes entry from list.
98 * @entry: the element to delete from the list.
99 *
100 * list_empty() on @entry does not return true after this, @entry is
101 * in an undefined state.
102 */
103 _INLINE_ void list_del(struct list_head *entry)
104 {
105 __list_del(entry->prev, entry->next);
106 }
107
108 /**
109 * list_del_init - deletes entry from list and reinitialize it.
110 * @entry: the element to delete from the list.
111 */
112 _INLINE_ void list_del_init(struct list_head *entry)
113 {
114 __list_del(entry->prev, entry->next);
115 INIT_LIST_HEAD(entry);
116 }
117
118 /**
119 * list_empty - tests whether a list is empty
120 * @head: the list to test.
121 */
122 _INLINE_ int list_empty(struct list_head *head)
123 {
124 return head->next == head;
125 }
126
127 /**
128 * list_entry_is_last - tests whether is entry last in the list
129 * @entry: the entry to test.
130 * @head: the list to test.
131 */
132 _INLINE_ int list_entry_is_last(struct list_head *entry, struct list_head *head)
133 {
134 return head->prev == entry;
135 }
136
137 /**
138 * list_splice - join two lists
139 * @list: the new list to add.
140 * @head: the place to add it in the first list.
141 */
142 _INLINE_ void list_splice(struct list_head *list, struct list_head *head)
143 {
144 struct list_head *first = list->next;
145
146 if (first != list) {
147 struct list_head *last = list->prev;
148 struct list_head *at = head->next;
149
150 first->prev = head;
151 head->next = first;
152
153 last->next = at;
154 at->prev = last;
155 }
156 }
157
158 /**
159 * list_entry - get the struct for this entry
160 * @ptr: the &struct list_head pointer.
161 * @type: the type of the struct this is embedded in.
162 * @member: the name of the list_struct within the struct.
163 */
164 #define list_entry(ptr, type, member) __extension__ ({ \
165 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
166 (type *)( (char *)__mptr - offsetof(type,member) );})
167
168
169 #define list_first_entry(head, type, member) \
170 ((head) && (head)->next != (head) ? list_entry((head)->next, type, member) : NULL)
171
172 #define list_last_entry(head, type, member) \
173 ((head) && (head)->prev != (head) ? list_entry((head)->prev, type, member) : NULL)
174
175 /**
176 * list_for_each - iterate over elements in a list
177 * @pos: the &struct list_head to use as a loop counter.
178 * @head: the head for your list.
179 */
180 #define list_for_each(pos, head) \
181 for (pos = (head)->next; pos != (head); pos = pos->next)
182
183 /**
184 * list_for_each_backwardly - iterate over elements in a list in reverse
185 * @pos: the &struct list_head to use as a loop counter.
186 * @head: the head for your list.
187 */
188 #define list_for_each_backwardly(pos, head) \
189 for (pos = (head)->prev; pos != (head); pos = pos->prev)
190
191 /**
192 * list_for_each_safe - iterate over elements in a list, but don't dereference
193 * pos after the body is done (in case it is freed)
194 * @pos: the &struct list_head to use as a loop counter.
195 * @pnext: the &struct list_head to use as a pointer to the next item.
196 * @head: the head for your list (not included in iteration).
197 */
198 #define list_for_each_safe(pos, pnext, head) \
199 for (pos = (head)->next, pnext = pos->next; pos != (head); \
200 pos = pnext, pnext = pos->next)
201
202 #define MAX_LIST_LENGTH_BITS 20
203
204 /*
205 * Returns a list organized in an intermediate format suited
206 * to chaining of merge() calls: null-terminated, no reserved or
207 * sentinel head node, "prev" links not maintained.
208 */
209 _INLINE_ struct list_head *merge(int (*cmp)(struct list_head *a,
210 struct list_head *b,
211 void *data),
212 void *data,
213 struct list_head *a, struct list_head *b)
214 {
215 struct list_head head, *tail = &head;
216
217 while (a && b) {
218 /* if equal, take 'a' -- important for sort stability */
219 if ((*cmp)(a, b, data) <= 0) {
220 tail->next = a;
221 a = a->next;
222 } else {
223 tail->next = b;
224 b = b->next;
225 }
226 tail = tail->next;
227 }
228 tail->next = a ? a : b;
229 return head.next;
230 }
231
232 /*
233 * Combine final list merge with restoration of standard doubly-linked
234 * list structure. This approach duplicates code from merge(), but
235 * runs faster than the tidier alternatives of either a separate final
236 * prev-link restoration pass, or maintaining the prev links
237 * throughout.
238 */
239 _INLINE_ void merge_and_restore_back_links(int (*cmp)(struct list_head *a,
240 struct list_head *b,
241 void *data),
242 void *data,
243 struct list_head *head,
244 struct list_head *a, struct list_head *b)
245 {
246 struct list_head *tail = head;
247
248 while (a && b) {
249 /* if equal, take 'a' -- important for sort stability */
250 if ((*cmp)(a, b, data) <= 0) {
251 tail->next = a;
252 a->prev = tail;
253 a = a->next;
254 } else {
255 tail->next = b;
256 b->prev = tail;
257 b = b->next;
258 }
259 tail = tail->next;
260 }
261 tail->next = a ? a : b;
262
263 do {
264 /*
265 * In worst cases this loop may run many iterations.
266 * Continue callbacks to the client even though no
267 * element comparison is needed, so the client's cmp()
268 * routine can invoke cond_resched() periodically.
269 */
270 (*cmp)(tail->next, tail->next, data);
271
272 tail->next->prev = tail;
273 tail = tail->next;
274 } while (tail->next);
275
276 tail->next = head;
277 head->prev = tail;
278 }
279
280
281 /**
282 * list_sort - sort a list
283 * @head: the list to sort
284 * @cmp: the elements comparison function
285 *
286 * This function implements "merge sort", which has O(nlog(n))
287 * complexity.
288 *
289 * The comparison function @cmp must return a negative value if @a
290 * should sort before @b, and a positive value if @a should sort after
291 * @b. If @a and @b are equivalent, and their original relative
292 * ordering is to be preserved, @cmp must return 0.
293 */
294 _INLINE_ void list_sort(struct list_head *head,
295 int (*cmp)(struct list_head *a,
296 struct list_head *b,
297 void *data),
298 void *data)
299 {
300 struct list_head *part[MAX_LIST_LENGTH_BITS+1]; /* sorted partial lists
301 -- last slot is a sentinel */
302 size_t lev; /* index into part[] */
303 size_t max_lev = 0;
304 struct list_head *list;
305
306 if (list_empty(head))
307 return;
308
309 memset(part, 0, sizeof(part));
310
311 head->prev->next = NULL;
312 list = head->next;
313
314 while (list) {
315 struct list_head *cur = list;
316 list = list->next;
317 cur->next = NULL;
318
319 for (lev = 0; part[lev]; lev++) {
320 cur = merge(cmp, data, part[lev], cur);
321 part[lev] = NULL;
322 }
323 if (lev > max_lev) {
324 /* list passed to list_sort() too long for efficiency */
325 if (lev >= ARRAY_SIZE(part) - 1)
326 lev--;
327 max_lev = lev;
328 }
329 part[lev] = cur;
330 }
331
332 for (lev = 0; lev < max_lev; lev++)
333 if (part[lev])
334 list = merge(cmp, data, part[lev], list);
335
336 merge_and_restore_back_links(cmp, data, head, part[max_lev], list);
337 }
338
339 #undef _INLINE_
340
341 #endif /* UTIL_LINUX_LIST_H */