Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
3254 Serge 1
/*
2
 * Copyright © 2010-2012 Intel Corporation
3
 * Copyright © 2010 Francisco Jerez 
4
 *
5
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * copy of this software and associated documentation files (the "Software"),
7
 * to deal in the Software without restriction, including without limitation
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
 * and/or sell copies of the Software, and to permit persons to whom the
10
 * Software is furnished to do so, subject to the following conditions:
11
 *
12
 * The above copyright notice and this permission notice (including the next
13
 * paragraph) shall be included in all copies or substantial portions of the
14
 * Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22
 * IN THE SOFTWARE.
23
 *
24
 */
25
 
26
#ifndef _INTEL_LIST_H_
27
#define _INTEL_LIST_H_
28
 
29
#include 
30
 
31
/**
32
 * @file Classic doubly-link circular list implementation.
33
 * For real usage examples of the linked list, see the file test/list.c
34
 *
35
 * Example:
36
 * We need to keep a list of struct foo in the parent struct bar, i.e. what
37
 * we want is something like this.
38
 *
39
 *     struct bar {
40
 *          ...
41
 *          struct foo *list_of_foos; -----> struct foo {}, struct foo {}, struct foo{}
42
 *          ...
43
 *     }
44
 *
45
 * We need one list head in bar and a list element in all list_of_foos (both are of
46
 * data type 'struct list').
47
 *
48
 *     struct bar {
49
 *          ...
50
 *          struct list list_of_foos;
51
 *          ...
52
 *     }
53
 *
54
 *     struct foo {
55
 *          ...
56
 *          struct list entry;
57
 *          ...
58
 *     }
59
 *
60
 * Now we initialize the list head:
61
 *
62
 *     struct bar bar;
63
 *     ...
64
 *     list_init(&bar.list_of_foos);
65
 *
66
 * Then we create the first element and add it to this list:
67
 *
68
 *     struct foo *foo = malloc(...);
69
 *     ....
70
 *     list_add(&foo->entry, &bar.list_of_foos);
71
 *
72
 * Repeat the above for each element you want to add to the list. Deleting
73
 * works with the element itself.
74
 *      list_del(&foo->entry);
75
 *      free(foo);
76
 *
77
 * Note: calling list_del(&bar.list_of_foos) will set bar.list_of_foos to an empty
78
 * list again.
79
 *
80
 * Looping through the list requires a 'struct foo' as iterator and the
81
 * name of the field the subnodes use.
82
 *
83
 * struct foo *iterator;
84
 * list_for_each_entry(iterator, &bar.list_of_foos, entry) {
85
 *      if (iterator->something == ...)
86
 *             ...
87
 * }
88
 *
89
 * Note: You must not call list_del() on the iterator if you continue the
90
 * loop. You need to run the safe for-each loop instead:
91
 *
92
 * struct foo *iterator, *next;
93
 * list_for_each_entry_safe(iterator, next, &bar.list_of_foos, entry) {
94
 *      if (...)
95
 *              list_del(&iterator->entry);
96
 * }
97
 *
98
 */
99
 
100
/**
101
 * The linkage struct for list nodes. This struct must be part of your
102
 * to-be-linked struct. struct list is required for both the head of the
103
 * list and for each list node.
104
 *
105
 * Position and name of the struct list field is irrelevant.
106
 * There are no requirements that elements of a list are of the same type.
107
 * There are no requirements for a list head, any struct list can be a list
108
 * head.
109
 */
110
struct list {
111
    struct list *next, *prev;
112
};
113
 
114
/**
115
 * Initialize the list as an empty list.
116
 *
117
 * Example:
118
 * list_init(&bar->list_of_foos);
119
 *
120
 * @param The list to initialized.
121
 */
122
static void
123
list_init(struct list *list)
124
{
125
    list->next = list->prev = list;
126
}
127
 
128
static inline void
129
__list_add(struct list *entry,
130
	    struct list *prev,
131
	    struct list *next)
132
{
133
    next->prev = entry;
134
    entry->next = next;
135
    entry->prev = prev;
136
    prev->next = entry;
137
}
138
 
139
/**
140
 * Insert a new element after the given list head. The new element does not
141
 * need to be initialised as empty list.
142
 * The list changes from:
143
 *      head → some element → ...
144
 * to
145
 *      head → new element → older element → ...
146
 *
147
 * Example:
148
 * struct foo *newfoo = malloc(...);
149
 * list_add(&newfoo->entry, &bar->list_of_foos);
150
 *
151
 * @param entry The new element to prepend to the list.
152
 * @param head The existing list.
153
 */
154
static inline void
155
list_add(struct list *entry, struct list *head)
156
{
157
    __list_add(entry, head, head->next);
158
}
159
 
160
static inline void
161
list_add_tail(struct list *entry, struct list *head)
162
{
163
    __list_add(entry, head->prev, head);
164
}
165
 
166
static inline void list_replace(struct list *old,
167
				struct list *new)
168
{
169
	new->next = old->next;
170
	new->next->prev = new;
171
	new->prev = old->prev;
172
	new->prev->next = new;
173
}
174
 
175
#define list_last_entry(ptr, type, member) \
176
    list_entry((ptr)->prev, type, member)
177
 
178
#define list_for_each(pos, head)				\
179
    for (pos = (head)->next; pos != (head); pos = pos->next)
180
 
181
/**
182
 * Append a new element to the end of the list given with this list head.
183
 *
184
 * The list changes from:
185
 *      head → some element → ... → lastelement
186
 * to
187
 *      head → some element → ... → lastelement → new element
188
 *
189
 * Example:
190
 * struct foo *newfoo = malloc(...);
191
 * list_append(&newfoo->entry, &bar->list_of_foos);
192
 *
193
 * @param entry The new element to prepend to the list.
194
 * @param head The existing list.
195
 */
196
static inline void
197
list_append(struct list *entry, struct list *head)
198
{
199
    __list_add(entry, head->prev, head);
200
}
201
 
202
 
203
static inline void
204
__list_del(struct list *prev, struct list *next)
205
{
206
	assert(next->prev == prev->next);
207
	next->prev = prev;
208
	prev->next = next;
209
}
210
 
211
static inline void
212
_list_del(struct list *entry)
213
{
214
    assert(entry->prev->next == entry);
215
    assert(entry->next->prev == entry);
216
    __list_del(entry->prev, entry->next);
217
}
218
 
219
/**
220
 * Remove the element from the list it is in. Using this function will reset
221
 * the pointers to/from this element so it is removed from the list. It does
222
 * NOT free the element itself or manipulate it otherwise.
223
 *
224
 * Using list_del on a pure list head (like in the example at the top of
225
 * this file) will NOT remove the first element from
226
 * the list but rather reset the list as empty list.
227
 *
228
 * Example:
229
 * list_del(&foo->entry);
230
 *
231
 * @param entry The element to remove.
232
 */
233
static inline void
234
list_del(struct list *entry)
235
{
236
    _list_del(entry);
237
    list_init(entry);
238
}
239
 
240
static inline void list_move(struct list *list, struct list *head)
241
{
242
	if (list->prev != head) {
243
		_list_del(list);
244
		list_add(list, head);
245
	}
246
}
247
 
248
static inline void list_move_tail(struct list *list, struct list *head)
249
{
250
	_list_del(list);
251
	list_add_tail(list, head);
252
}
253
 
254
/**
255
 * Check if the list is empty.
256
 *
257
 * Example:
258
 * list_is_empty(&bar->list_of_foos);
259
 *
260
 * @return True if the list contains one or more elements or False otherwise.
261
 */
262
static inline bool
263
list_is_empty(struct list *head)
264
{
265
    return head->next == head;
266
}
267
 
268
/**
269
 * Alias of container_of
270
 */
271
#define list_entry(ptr, type, member) \
272
    container_of(ptr, type, member)
273
 
274
/**
275
 * Retrieve the first list entry for the given list pointer.
276
 *
277
 * Example:
278
 * struct foo *first;
279
 * first = list_first_entry(&bar->list_of_foos, struct foo, list_of_foos);
280
 *
281
 * @param ptr The list head
282
 * @param type Data type of the list element to retrieve
283
 * @param member Member name of the struct list field in the list element.
284
 * @return A pointer to the first list element.
285
 */
286
#define list_first_entry(ptr, type, member) \
287
    list_entry((ptr)->next, type, member)
288
 
289
/**
290
 * Retrieve the last list entry for the given listpointer.
291
 *
292
 * Example:
293
 * struct foo *first;
294
 * first = list_last_entry(&bar->list_of_foos, struct foo, list_of_foos);
295
 *
296
 * @param ptr The list head
297
 * @param type Data type of the list element to retrieve
298
 * @param member Member name of the struct list field in the list element.
299
 * @return A pointer to the last list element.
300
 */
301
#define list_last_entry(ptr, type, member) \
302
    list_entry((ptr)->prev, type, member)
303
 
304
#define __container_of(ptr, sample, member)				\
305
    (void *)((char *)(ptr)						\
306
	     - ((char *)&(sample)->member - (char *)(sample)))
307
/**
308
 * Loop through the list given by head and set pos to struct in the list.
309
 *
310
 * Example:
311
 * struct foo *iterator;
312
 * list_for_each_entry(iterator, &bar->list_of_foos, entry) {
313
 *      [modify iterator]
314
 * }
315
 *
316
 * This macro is not safe for node deletion. Use list_for_each_entry_safe
317
 * instead.
318
 *
319
 * @param pos Iterator variable of the type of the list elements.
320
 * @param head List head
321
 * @param member Member name of the struct list in the list elements.
322
 *
323
 */
324
#define list_for_each_entry(pos, head, member)				\
325
    for (pos = __container_of((head)->next, pos, member);		\
326
	 &pos->member != (head);					\
327
	 pos = __container_of(pos->member.next, pos, member))
328
 
329
#define list_for_each_entry_reverse(pos, head, member)				\
330
    for (pos = __container_of((head)->prev, pos, member);		\
331
	 &pos->member != (head);					\
332
	 pos = __container_of(pos->member.prev, pos, member))
333
 
334
/**
335
 * Loop through the list, keeping a backup pointer to the element. This
336
 * macro allows for the deletion of a list element while looping through the
337
 * list.
338
 *
339
 * See list_for_each_entry for more details.
340
 */
341
#define list_for_each_entry_safe(pos, tmp, head, member)		\
342
    for (pos = __container_of((head)->next, pos, member),		\
343
	 tmp = __container_of(pos->member.next, pos, member);		\
344
	 &pos->member != (head);					\
345
	 pos = tmp, tmp = __container_of(pos->member.next, tmp, member))
346
 
347
 
348
#undef container_of
349
#define container_of(ptr, type, member) \
350
	((type *)((char *)(ptr) - (char *) &((type *)0)->member))
351
 
352
#endif /* _INTEL_LIST_H_ */
353