1428d7b3dSmrg/*
2428d7b3dSmrg * Copyright © 2010-2012 Intel Corporation
3428d7b3dSmrg * Copyright © 2010 Francisco Jerez <currojerez@riseup.net>
4428d7b3dSmrg *
5428d7b3dSmrg * Permission is hereby granted, free of charge, to any person obtaining a
6428d7b3dSmrg * copy of this software and associated documentation files (the "Software"),
7428d7b3dSmrg * to deal in the Software without restriction, including without limitation
8428d7b3dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9428d7b3dSmrg * and/or sell copies of the Software, and to permit persons to whom the
10428d7b3dSmrg * Software is furnished to do so, subject to the following conditions:
11428d7b3dSmrg *
12428d7b3dSmrg * The above copyright notice and this permission notice (including the next
13428d7b3dSmrg * paragraph) shall be included in all copies or substantial portions of the
14428d7b3dSmrg * Software.
15428d7b3dSmrg *
16428d7b3dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17428d7b3dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18428d7b3dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19428d7b3dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20428d7b3dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21428d7b3dSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22428d7b3dSmrg * IN THE SOFTWARE.
23428d7b3dSmrg *
24428d7b3dSmrg */
25428d7b3dSmrg
26428d7b3dSmrg#ifndef _INTEL_LIST_H_
27428d7b3dSmrg#define _INTEL_LIST_H_
28428d7b3dSmrg
29428d7b3dSmrg#include <xorgVersion.h>
30428d7b3dSmrg
31428d7b3dSmrg#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1,9,0,0,0) || XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,11,99,903,0)
32428d7b3dSmrg
33428d7b3dSmrg#include <stdbool.h>
34428d7b3dSmrg
35428d7b3dSmrg/**
36428d7b3dSmrg * @file Classic doubly-link circular list implementation.
37428d7b3dSmrg * For real usage examples of the linked list, see the file test/list.c
38428d7b3dSmrg *
39428d7b3dSmrg * Example:
40428d7b3dSmrg * We need to keep a list of struct foo in the parent struct bar, i.e. what
41428d7b3dSmrg * we want is something like this.
42428d7b3dSmrg *
43428d7b3dSmrg *     struct bar {
44428d7b3dSmrg *          ...
45428d7b3dSmrg *          struct foo *list_of_foos; -----> struct foo {}, struct foo {}, struct foo{}
46428d7b3dSmrg *          ...
47428d7b3dSmrg *     }
48428d7b3dSmrg *
49428d7b3dSmrg * We need one list head in bar and a list element in all list_of_foos (both are of
50428d7b3dSmrg * data type 'struct list').
51428d7b3dSmrg *
52428d7b3dSmrg *     struct bar {
53428d7b3dSmrg *          ...
54428d7b3dSmrg *          struct list list_of_foos;
55428d7b3dSmrg *          ...
56428d7b3dSmrg *     }
57428d7b3dSmrg *
58428d7b3dSmrg *     struct foo {
59428d7b3dSmrg *          ...
60428d7b3dSmrg *          struct list entry;
61428d7b3dSmrg *          ...
62428d7b3dSmrg *     }
63428d7b3dSmrg *
64428d7b3dSmrg * Now we initialize the list head:
65428d7b3dSmrg *
66428d7b3dSmrg *     struct bar bar;
67428d7b3dSmrg *     ...
68428d7b3dSmrg *     list_init(&bar.list_of_foos);
69428d7b3dSmrg *
70428d7b3dSmrg * Then we create the first element and add it to this list:
71428d7b3dSmrg *
72428d7b3dSmrg *     struct foo *foo = malloc(...);
73428d7b3dSmrg *     ....
74428d7b3dSmrg *     list_add(&foo->entry, &bar.list_of_foos);
75428d7b3dSmrg *
76428d7b3dSmrg * Repeat the above for each element you want to add to the list. Deleting
77428d7b3dSmrg * works with the element itself.
78428d7b3dSmrg *      list_del(&foo->entry);
79428d7b3dSmrg *      free(foo);
80428d7b3dSmrg *
81428d7b3dSmrg * Note: calling list_del(&bar.list_of_foos) will set bar.list_of_foos to an empty
82428d7b3dSmrg * list again.
83428d7b3dSmrg *
84428d7b3dSmrg * Looping through the list requires a 'struct foo' as iterator and the
85428d7b3dSmrg * name of the field the subnodes use.
86428d7b3dSmrg *
87428d7b3dSmrg * struct foo *iterator;
88428d7b3dSmrg * list_for_each_entry(iterator, &bar.list_of_foos, entry) {
89428d7b3dSmrg *      if (iterator->something == ...)
90428d7b3dSmrg *             ...
91428d7b3dSmrg * }
92428d7b3dSmrg *
93428d7b3dSmrg * Note: You must not call list_del() on the iterator if you continue the
94428d7b3dSmrg * loop. You need to run the safe for-each loop instead:
95428d7b3dSmrg *
96428d7b3dSmrg * struct foo *iterator, *next;
97428d7b3dSmrg * list_for_each_entry_safe(iterator, next, &bar.list_of_foos, entry) {
98428d7b3dSmrg *      if (...)
99428d7b3dSmrg *              list_del(&iterator->entry);
100428d7b3dSmrg * }
101428d7b3dSmrg *
102428d7b3dSmrg */
103428d7b3dSmrg
104428d7b3dSmrg/**
105428d7b3dSmrg * The linkage struct for list nodes. This struct must be part of your
106428d7b3dSmrg * to-be-linked struct. struct list is required for both the head of the
107428d7b3dSmrg * list and for each list node.
108428d7b3dSmrg *
109428d7b3dSmrg * Position and name of the struct list field is irrelevant.
110428d7b3dSmrg * There are no requirements that elements of a list are of the same type.
111428d7b3dSmrg * There are no requirements for a list head, any struct list can be a list
112428d7b3dSmrg * head.
113428d7b3dSmrg */
114428d7b3dSmrgstruct list {
115428d7b3dSmrg    struct list *next, *prev;
116428d7b3dSmrg};
117428d7b3dSmrg
118428d7b3dSmrg/**
119428d7b3dSmrg * Initialize the list as an empty list.
120428d7b3dSmrg *
121428d7b3dSmrg * Example:
122428d7b3dSmrg * list_init(&bar->list_of_foos);
123428d7b3dSmrg *
124428d7b3dSmrg * @param The list to initialized.
125428d7b3dSmrg */
126428d7b3dSmrgstatic void
127428d7b3dSmrglist_init(struct list *list)
128428d7b3dSmrg{
129428d7b3dSmrg    list->next = list->prev = list;
130428d7b3dSmrg}
131428d7b3dSmrg
132428d7b3dSmrgstatic inline void
133428d7b3dSmrg__list_add(struct list *entry,
134428d7b3dSmrg	    struct list *prev,
135428d7b3dSmrg	    struct list *next)
136428d7b3dSmrg{
137428d7b3dSmrg    next->prev = entry;
138428d7b3dSmrg    entry->next = next;
139428d7b3dSmrg    entry->prev = prev;
140428d7b3dSmrg    prev->next = entry;
141428d7b3dSmrg}
142428d7b3dSmrg
143428d7b3dSmrg/**
144428d7b3dSmrg * Insert a new element after the given list head. The new element does not
145428d7b3dSmrg * need to be initialised as empty list.
146428d7b3dSmrg * The list changes from:
147428d7b3dSmrg *      head → some element → ...
148428d7b3dSmrg * to
149428d7b3dSmrg *      head → new element → older element → ...
150428d7b3dSmrg *
151428d7b3dSmrg * Example:
152428d7b3dSmrg * struct foo *newfoo = malloc(...);
153428d7b3dSmrg * list_add(&newfoo->entry, &bar->list_of_foos);
154428d7b3dSmrg *
155428d7b3dSmrg * @param entry The new element to prepend to the list.
156428d7b3dSmrg * @param head The existing list.
157428d7b3dSmrg */
158428d7b3dSmrgstatic inline void
159428d7b3dSmrglist_add(struct list *entry, struct list *head)
160428d7b3dSmrg{
161428d7b3dSmrg    __list_add(entry, head, head->next);
162428d7b3dSmrg}
163428d7b3dSmrg
164428d7b3dSmrgstatic inline void
165428d7b3dSmrglist_add_tail(struct list *entry, struct list *head)
166428d7b3dSmrg{
167428d7b3dSmrg    __list_add(entry, head->prev, head);
168428d7b3dSmrg}
169428d7b3dSmrg
170428d7b3dSmrgstatic inline void list_replace(struct list *old,
171428d7b3dSmrg				struct list *new)
172428d7b3dSmrg{
173428d7b3dSmrg	new->next = old->next;
174428d7b3dSmrg	new->next->prev = new;
175428d7b3dSmrg	new->prev = old->prev;
176428d7b3dSmrg	new->prev->next = new;
177428d7b3dSmrg}
178428d7b3dSmrg
179428d7b3dSmrg#define list_last_entry(ptr, type, member) \
180428d7b3dSmrg    list_entry((ptr)->prev, type, member)
181428d7b3dSmrg
182428d7b3dSmrg#define list_for_each(pos, head)				\
183428d7b3dSmrg    for (pos = (head)->next; pos != (head); pos = pos->next)
184428d7b3dSmrg
185428d7b3dSmrg/**
186428d7b3dSmrg * Append a new element to the end of the list given with this list head.
187428d7b3dSmrg *
188428d7b3dSmrg * The list changes from:
189428d7b3dSmrg *      head → some element → ... → lastelement
190428d7b3dSmrg * to
191428d7b3dSmrg *      head → some element → ... → lastelement → new element
192428d7b3dSmrg *
193428d7b3dSmrg * Example:
194428d7b3dSmrg * struct foo *newfoo = malloc(...);
195428d7b3dSmrg * list_append(&newfoo->entry, &bar->list_of_foos);
196428d7b3dSmrg *
197428d7b3dSmrg * @param entry The new element to prepend to the list.
198428d7b3dSmrg * @param head The existing list.
199428d7b3dSmrg */
200428d7b3dSmrgstatic inline void
201428d7b3dSmrglist_append(struct list *entry, struct list *head)
202428d7b3dSmrg{
203428d7b3dSmrg    __list_add(entry, head->prev, head);
204428d7b3dSmrg}
205428d7b3dSmrg
206428d7b3dSmrg
207428d7b3dSmrgstatic inline void
208428d7b3dSmrg__list_del(struct list *prev, struct list *next)
209428d7b3dSmrg{
210428d7b3dSmrg	assert(next->prev == prev->next);
211428d7b3dSmrg	next->prev = prev;
212428d7b3dSmrg	prev->next = next;
213428d7b3dSmrg}
214428d7b3dSmrg
215428d7b3dSmrgstatic inline void
216428d7b3dSmrg_list_del(struct list *entry)
217428d7b3dSmrg{
218428d7b3dSmrg    assert(entry->prev->next == entry);
219428d7b3dSmrg    assert(entry->next->prev == entry);
220428d7b3dSmrg    __list_del(entry->prev, entry->next);
221428d7b3dSmrg}
222428d7b3dSmrg
223428d7b3dSmrg/**
224428d7b3dSmrg * Remove the element from the list it is in. Using this function will reset
225428d7b3dSmrg * the pointers to/from this element so it is removed from the list. It does
226428d7b3dSmrg * NOT free the element itself or manipulate it otherwise.
227428d7b3dSmrg *
228428d7b3dSmrg * Using list_del on a pure list head (like in the example at the top of
229428d7b3dSmrg * this file) will NOT remove the first element from
230428d7b3dSmrg * the list but rather reset the list as empty list.
231428d7b3dSmrg *
232428d7b3dSmrg * Example:
233428d7b3dSmrg * list_del(&foo->entry);
234428d7b3dSmrg *
235428d7b3dSmrg * @param entry The element to remove.
236428d7b3dSmrg */
237428d7b3dSmrgstatic inline void
238428d7b3dSmrglist_del(struct list *entry)
239428d7b3dSmrg{
240428d7b3dSmrg    _list_del(entry);
241428d7b3dSmrg    list_init(entry);
242428d7b3dSmrg}
243428d7b3dSmrg
244428d7b3dSmrgstatic inline void list_move(struct list *list, struct list *head)
245428d7b3dSmrg{
246428d7b3dSmrg	if (list->prev != head) {
247428d7b3dSmrg		_list_del(list);
248428d7b3dSmrg		list_add(list, head);
249428d7b3dSmrg	}
250428d7b3dSmrg}
251428d7b3dSmrg
252428d7b3dSmrgstatic inline void list_move_tail(struct list *list, struct list *head)
253428d7b3dSmrg{
254428d7b3dSmrg	_list_del(list);
255428d7b3dSmrg	list_add_tail(list, head);
256428d7b3dSmrg}
257428d7b3dSmrg
258428d7b3dSmrg/**
259428d7b3dSmrg * Check if the list is empty.
260428d7b3dSmrg *
261428d7b3dSmrg * Example:
262428d7b3dSmrg * list_is_empty(&bar->list_of_foos);
263428d7b3dSmrg *
264428d7b3dSmrg * @return True if the list contains one or more elements or False otherwise.
265428d7b3dSmrg */
266428d7b3dSmrgstatic inline bool
267428d7b3dSmrglist_is_empty(const struct list *head)
268428d7b3dSmrg{
269428d7b3dSmrg    return head->next == head;
270428d7b3dSmrg}
271428d7b3dSmrg
272428d7b3dSmrg/**
273428d7b3dSmrg * Alias of container_of
274428d7b3dSmrg */
275428d7b3dSmrg#define list_entry(ptr, type, member) \
276428d7b3dSmrg    container_of(ptr, type, member)
277428d7b3dSmrg
278428d7b3dSmrg/**
279428d7b3dSmrg * Retrieve the first list entry for the given list pointer.
280428d7b3dSmrg *
281428d7b3dSmrg * Example:
282428d7b3dSmrg * struct foo *first;
283428d7b3dSmrg * first = list_first_entry(&bar->list_of_foos, struct foo, list_of_foos);
284428d7b3dSmrg *
285428d7b3dSmrg * @param ptr The list head
286428d7b3dSmrg * @param type Data type of the list element to retrieve
287428d7b3dSmrg * @param member Member name of the struct list field in the list element.
288428d7b3dSmrg * @return A pointer to the first list element.
289428d7b3dSmrg */
290428d7b3dSmrg#define list_first_entry(ptr, type, member) \
291428d7b3dSmrg    list_entry((ptr)->next, type, member)
292428d7b3dSmrg
293428d7b3dSmrg/**
294428d7b3dSmrg * Retrieve the last list entry for the given listpointer.
295428d7b3dSmrg *
296428d7b3dSmrg * Example:
297428d7b3dSmrg * struct foo *first;
298428d7b3dSmrg * first = list_last_entry(&bar->list_of_foos, struct foo, list_of_foos);
299428d7b3dSmrg *
300428d7b3dSmrg * @param ptr The list head
301428d7b3dSmrg * @param type Data type of the list element to retrieve
302428d7b3dSmrg * @param member Member name of the struct list field in the list element.
303428d7b3dSmrg * @return A pointer to the last list element.
304428d7b3dSmrg */
305428d7b3dSmrg#define list_last_entry(ptr, type, member) \
306428d7b3dSmrg    list_entry((ptr)->prev, type, member)
307428d7b3dSmrg
308428d7b3dSmrg#ifdef HAVE_TYPEOF
309428d7b3dSmrg#define __container_of(ptr, sample, member)			\
310428d7b3dSmrg    container_of(ptr, typeof(*sample), member)
311428d7b3dSmrg#else
312428d7b3dSmrg/* This implementation of __container_of has undefined behavior according
313428d7b3dSmrg * to the C standard, but it works in many cases.  If your compiler doesn't
314428d7b3dSmrg * support typeof() and fails with this implementation, please try a newer
315428d7b3dSmrg * compiler.
316428d7b3dSmrg */
317428d7b3dSmrg#define __container_of(ptr, sample, member)                            \
318428d7b3dSmrg    (void *)((char *)(ptr)                                             \
319428d7b3dSmrg            - ((char *)&(sample)->member - (char *)(sample)))
320428d7b3dSmrg#endif
321428d7b3dSmrg
322428d7b3dSmrg/**
323428d7b3dSmrg * Loop through the list given by head and set pos to struct in the list.
324428d7b3dSmrg *
325428d7b3dSmrg * Example:
326428d7b3dSmrg * struct foo *iterator;
327428d7b3dSmrg * list_for_each_entry(iterator, &bar->list_of_foos, entry) {
328428d7b3dSmrg *      [modify iterator]
329428d7b3dSmrg * }
330428d7b3dSmrg *
331428d7b3dSmrg * This macro is not safe for node deletion. Use list_for_each_entry_safe
332428d7b3dSmrg * instead.
333428d7b3dSmrg *
334428d7b3dSmrg * @param pos Iterator variable of the type of the list elements.
335428d7b3dSmrg * @param head List head
336428d7b3dSmrg * @param member Member name of the struct list in the list elements.
337428d7b3dSmrg *
338428d7b3dSmrg */
339428d7b3dSmrg#define list_for_each_entry(pos, head, member)				\
340428d7b3dSmrg    for (pos = NULL,                                                    \
341428d7b3dSmrg         pos = __container_of((head)->next, pos, member);		\
342428d7b3dSmrg	 &pos->member != (head);					\
343428d7b3dSmrg	 pos = __container_of(pos->member.next, pos, member))
344428d7b3dSmrg
345428d7b3dSmrg#define list_for_each_entry_reverse(pos, head, member)				\
346428d7b3dSmrg    for (pos = NULL,                                                    \
347428d7b3dSmrg         pos = __container_of((head)->prev, pos, member);		\
348428d7b3dSmrg	 &pos->member != (head);					\
349428d7b3dSmrg	 pos = __container_of(pos->member.prev, pos, member))
350428d7b3dSmrg
351428d7b3dSmrg/**
352428d7b3dSmrg * Loop through the list, keeping a backup pointer to the element. This
353428d7b3dSmrg * macro allows for the deletion of a list element while looping through the
354428d7b3dSmrg * list.
355428d7b3dSmrg *
356428d7b3dSmrg * See list_for_each_entry for more details.
357428d7b3dSmrg */
358428d7b3dSmrg#define list_for_each_entry_safe(pos, tmp, head, member)		\
359428d7b3dSmrg    for (pos = NULL,                                                    \
360428d7b3dSmrg         pos = __container_of((head)->next, pos, member),		\
361428d7b3dSmrg	 tmp = __container_of(pos->member.next, pos, member);		\
362428d7b3dSmrg	 &pos->member != (head);					\
363428d7b3dSmrg	 pos = tmp, tmp = __container_of(pos->member.next, tmp, member))
364428d7b3dSmrg
365428d7b3dSmrg#else
366428d7b3dSmrg
367428d7b3dSmrg#include <list.h>
368428d7b3dSmrg
369428d7b3dSmrgstatic inline void
370428d7b3dSmrglist_add_tail(struct list *entry, struct list *head)
371428d7b3dSmrg{
372428d7b3dSmrg    __list_add(entry, head->prev, head);
373428d7b3dSmrg}
374428d7b3dSmrg
375428d7b3dSmrgstatic inline void
376428d7b3dSmrg_list_del(struct list *entry)
377428d7b3dSmrg{
378428d7b3dSmrg    assert(entry->prev->next == entry);
379428d7b3dSmrg    assert(entry->next->prev == entry);
380428d7b3dSmrg    __list_del(entry->prev, entry->next);
381428d7b3dSmrg}
382428d7b3dSmrg
383428d7b3dSmrgstatic inline void list_replace(struct list *old,
384428d7b3dSmrg				struct list *new)
385428d7b3dSmrg{
386428d7b3dSmrg	new->next = old->next;
387428d7b3dSmrg	new->next->prev = new;
388428d7b3dSmrg	new->prev = old->prev;
389428d7b3dSmrg	new->prev->next = new;
390428d7b3dSmrg}
391428d7b3dSmrg
392428d7b3dSmrgstatic inline void list_move(struct list *list, struct list *head)
393428d7b3dSmrg{
394428d7b3dSmrg	if (list->prev != head) {
395428d7b3dSmrg		_list_del(list);
396428d7b3dSmrg		list_add(list, head);
397428d7b3dSmrg	}
398428d7b3dSmrg}
399428d7b3dSmrg
400428d7b3dSmrgstatic inline void list_move_tail(struct list *list, struct list *head)
401428d7b3dSmrg{
402428d7b3dSmrg	_list_del(list);
403428d7b3dSmrg	list_add_tail(list, head);
404428d7b3dSmrg}
405428d7b3dSmrg
406428d7b3dSmrg#define list_last_entry(ptr, type, member) \
407428d7b3dSmrg    list_entry((ptr)->prev, type, member)
408428d7b3dSmrg
409428d7b3dSmrg#define list_for_each_entry_reverse(pos, head, member)				\
410428d7b3dSmrg    for (pos = __container_of((head)->prev, pos, member);		\
411428d7b3dSmrg	 &pos->member != (head);					\
412428d7b3dSmrg	 pos = __container_of(pos->member.prev, pos, member))
413428d7b3dSmrg
414428d7b3dSmrg#endif
415428d7b3dSmrg
416428d7b3dSmrg#undef container_of
417428d7b3dSmrg#define container_of(ptr, type, member) \
418428d7b3dSmrg	((type *)((char *)(ptr) - (char *) &((type *)0)->member))
419428d7b3dSmrg
420428d7b3dSmrgstatic inline int list_is_singular(const struct list *list)
421428d7b3dSmrg{
422428d7b3dSmrg	return list->next == list->prev;
423428d7b3dSmrg}
424428d7b3dSmrg
425428d7b3dSmrg#endif /* _INTEL_LIST_H_ */
426428d7b3dSmrg
427