• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2008, 2010 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 /**
25  * \file list.h
26  * \brief Doubly-linked list abstract container type.
27  *
28  * Each doubly-linked list has a sentinel head and tail node.  These nodes
29  * contain no data.  The head sentinel can be identified by its \c prev
30  * pointer being \c NULL.  The tail sentinel can be identified by its
31  * \c next pointer being \c NULL.
32  *
33  * A list is empty if either the head sentinel's \c next pointer points to the
34  * tail sentinel or the tail sentinel's \c prev poiner points to the head
35  * sentinel. The head sentinel and tail sentinel nodes are allocated within the
36  * list structure.
37  *
38  * Do note that this means that the list nodes will contain pointers into the
39  * list structure itself and as a result you may not \c realloc() an  \c
40  * exec_list or any structure in which an \c exec_list is embedded.
41  */
42 
43 #ifndef LIST_CONTAINER_H
44 #define LIST_CONTAINER_H
45 
46 #ifndef __cplusplus
47 #include <stddef.h>
48 #endif
49 #include <assert.h>
50 
51 #include "util/ralloc.h"
52 
53 struct exec_node {
54    struct exec_node *next;
55    struct exec_node *prev;
56 
57 #ifdef __cplusplus
58    DECLARE_RZALLOC_CXX_OPERATORS(exec_node)
59 
exec_nodeexec_node60    exec_node() : next(NULL), prev(NULL)
61    {
62       /* empty */
63    }
64 
65    const exec_node *get_next() const;
66    exec_node *get_next();
67 
68    const exec_node *get_prev() const;
69    exec_node *get_prev();
70 
71    void remove();
72 
73    /**
74     * Link a node with itself
75     *
76     * This creates a sort of degenerate list that is occasionally useful.
77     */
78    void self_link();
79 
80    /**
81     * Insert a node in the list after the current node
82     */
83    void insert_after(exec_node *after);
84    /**
85     * Insert a node in the list before the current node
86     */
87    void insert_before(exec_node *before);
88 
89    /**
90     * Insert another list in the list before the current node
91     */
92    void insert_before(struct exec_list *before);
93 
94    /**
95     * Replace the current node with the given node.
96     */
97    void replace_with(exec_node *replacement);
98 
99    /**
100     * Is this the sentinel at the tail of the list?
101     */
102    bool is_tail_sentinel() const;
103 
104    /**
105     * Is this the sentinel at the head of the list?
106     */
107    bool is_head_sentinel() const;
108 #endif
109 };
110 
111 static inline void
exec_node_init(struct exec_node * n)112 exec_node_init(struct exec_node *n)
113 {
114    n->next = NULL;
115    n->prev = NULL;
116 }
117 
118 static inline const struct exec_node *
exec_node_get_next_const(const struct exec_node * n)119 exec_node_get_next_const(const struct exec_node *n)
120 {
121    return n->next;
122 }
123 
124 static inline struct exec_node *
exec_node_get_next(struct exec_node * n)125 exec_node_get_next(struct exec_node *n)
126 {
127    return n->next;
128 }
129 
130 static inline const struct exec_node *
exec_node_get_prev_const(const struct exec_node * n)131 exec_node_get_prev_const(const struct exec_node *n)
132 {
133    return n->prev;
134 }
135 
136 static inline struct exec_node *
exec_node_get_prev(struct exec_node * n)137 exec_node_get_prev(struct exec_node *n)
138 {
139    return n->prev;
140 }
141 
142 static inline void
exec_node_remove(struct exec_node * n)143 exec_node_remove(struct exec_node *n)
144 {
145    n->next->prev = n->prev;
146    n->prev->next = n->next;
147    n->next = NULL;
148    n->prev = NULL;
149 }
150 
151 static inline void
exec_node_self_link(struct exec_node * n)152 exec_node_self_link(struct exec_node *n)
153 {
154    n->next = n;
155    n->prev = n;
156 }
157 
158 static inline void
exec_node_insert_after(struct exec_node * n,struct exec_node * after)159 exec_node_insert_after(struct exec_node *n, struct exec_node *after)
160 {
161    after->next = n->next;
162    after->prev = n;
163 
164    n->next->prev = after;
165    n->next = after;
166 }
167 
168 static inline void
exec_node_insert_node_before(struct exec_node * n,struct exec_node * before)169 exec_node_insert_node_before(struct exec_node *n, struct exec_node *before)
170 {
171    before->next = n;
172    before->prev = n->prev;
173 
174    n->prev->next = before;
175    n->prev = before;
176 }
177 
178 static inline void
exec_node_replace_with(struct exec_node * n,struct exec_node * replacement)179 exec_node_replace_with(struct exec_node *n, struct exec_node *replacement)
180 {
181    replacement->prev = n->prev;
182    replacement->next = n->next;
183 
184    n->prev->next = replacement;
185    n->next->prev = replacement;
186 }
187 
188 static inline bool
exec_node_is_tail_sentinel(const struct exec_node * n)189 exec_node_is_tail_sentinel(const struct exec_node *n)
190 {
191    return n->next == NULL;
192 }
193 
194 static inline bool
exec_node_is_head_sentinel(const struct exec_node * n)195 exec_node_is_head_sentinel(const struct exec_node *n)
196 {
197    return n->prev == NULL;
198 }
199 
200 #ifdef __cplusplus
get_next()201 inline const exec_node *exec_node::get_next() const
202 {
203    return exec_node_get_next_const(this);
204 }
205 
get_next()206 inline exec_node *exec_node::get_next()
207 {
208    return exec_node_get_next(this);
209 }
210 
get_prev()211 inline const exec_node *exec_node::get_prev() const
212 {
213    return exec_node_get_prev_const(this);
214 }
215 
get_prev()216 inline exec_node *exec_node::get_prev()
217 {
218    return exec_node_get_prev(this);
219 }
220 
remove()221 inline void exec_node::remove()
222 {
223    exec_node_remove(this);
224 }
225 
self_link()226 inline void exec_node::self_link()
227 {
228    exec_node_self_link(this);
229 }
230 
insert_after(exec_node * after)231 inline void exec_node::insert_after(exec_node *after)
232 {
233    exec_node_insert_after(this, after);
234 }
235 
insert_before(exec_node * before)236 inline void exec_node::insert_before(exec_node *before)
237 {
238    exec_node_insert_node_before(this, before);
239 }
240 
replace_with(exec_node * replacement)241 inline void exec_node::replace_with(exec_node *replacement)
242 {
243    exec_node_replace_with(this, replacement);
244 }
245 
is_tail_sentinel()246 inline bool exec_node::is_tail_sentinel() const
247 {
248    return exec_node_is_tail_sentinel(this);
249 }
250 
is_head_sentinel()251 inline bool exec_node::is_head_sentinel() const
252 {
253    return exec_node_is_head_sentinel(this);
254 }
255 #endif
256 
257 #ifdef __cplusplus
258 /* This macro will not work correctly if `t' uses virtual inheritance.  If you
259  * are using virtual inheritance, you deserve a slow and painful death.  Enjoy!
260  */
261 #define exec_list_offsetof(t, f, p) \
262    (((char *) &((t *) p)->f) - ((char *) p))
263 #else
264 #define exec_list_offsetof(t, f, p) offsetof(t, f)
265 #endif
266 
267 /**
268  * Get a pointer to the structure containing an exec_node
269  *
270  * Given a pointer to an \c exec_node embedded in a structure, get a pointer to
271  * the containing structure.
272  *
273  * \param type  Base type of the structure containing the node
274  * \param node  Pointer to the \c exec_node
275  * \param field Name of the field in \c type that is the embedded \c exec_node
276  */
277 #define exec_node_data(type, node, field) \
278    ((type *) (((char *) node) - exec_list_offsetof(type, field, node)))
279 
280 #ifdef __cplusplus
281 struct exec_node;
282 #endif
283 
284 struct exec_list {
285    struct exec_node head_sentinel;
286    struct exec_node tail_sentinel;
287 
288 #ifdef __cplusplus
289    DECLARE_RALLOC_CXX_OPERATORS(exec_list)
290 
exec_listexec_list291    exec_list()
292    {
293       make_empty();
294    }
295 
296    void make_empty();
297 
298    bool is_empty() const;
299 
300    const exec_node *get_head() const;
301    exec_node *get_head();
302    const exec_node *get_head_raw() const;
303    exec_node *get_head_raw();
304 
305    const exec_node *get_tail() const;
306    exec_node *get_tail();
307    const exec_node *get_tail_raw() const;
308    exec_node *get_tail_raw();
309 
310    unsigned length() const;
311 
312    void push_head(exec_node *n);
313    void push_tail(exec_node *n);
314    void push_degenerate_list_at_head(exec_node *n);
315 
316    /**
317     * Remove the first node from a list and return it
318     *
319     * \return
320     * The first node in the list or \c NULL if the list is empty.
321     *
322     * \sa exec_list::get_head
323     */
324    exec_node *pop_head();
325 
326    /**
327     * Move all of the nodes from this list to the target list
328     */
329    void move_nodes_to(exec_list *target);
330 
331    /**
332     * Append all nodes from the source list to the end of the target list
333     */
334    void append_list(exec_list *source);
335 
336    /**
337     * Prepend all nodes from the source list to the beginning of the target
338     * list
339     */
340    void prepend_list(exec_list *source);
341 #endif
342 };
343 
344 static inline void
exec_list_make_empty(struct exec_list * list)345 exec_list_make_empty(struct exec_list *list)
346 {
347    list->head_sentinel.next = &list->tail_sentinel;
348    list->head_sentinel.prev = NULL;
349    list->tail_sentinel.next = NULL;
350    list->tail_sentinel.prev = &list->head_sentinel;
351 }
352 
353 static inline bool
exec_list_is_empty(const struct exec_list * list)354 exec_list_is_empty(const struct exec_list *list)
355 {
356    /* There are three ways to test whether a list is empty or not.
357     *
358     * - Check to see if the head sentinel's \c next is the tail sentinel.
359     * - Check to see if the tail sentinel's \c prev is the head sentinel.
360     * - Check to see if the head is the sentinel node by test whether its
361     *   \c next pointer is \c NULL.
362     *
363     * The first two methods tend to generate better code on modern systems
364     * because they save a pointer dereference.
365     */
366    return list->head_sentinel.next == &list->tail_sentinel;
367 }
368 
369 static inline const struct exec_node *
exec_list_get_head_const(const struct exec_list * list)370 exec_list_get_head_const(const struct exec_list *list)
371 {
372    return !exec_list_is_empty(list) ? list->head_sentinel.next : NULL;
373 }
374 
375 static inline struct exec_node *
exec_list_get_head(struct exec_list * list)376 exec_list_get_head(struct exec_list *list)
377 {
378    return !exec_list_is_empty(list) ? list->head_sentinel.next : NULL;
379 }
380 
381 static inline const struct exec_node *
exec_list_get_head_raw_const(const struct exec_list * list)382 exec_list_get_head_raw_const(const struct exec_list *list)
383 {
384    return list->head_sentinel.next;
385 }
386 
387 static inline struct exec_node *
exec_list_get_head_raw(struct exec_list * list)388 exec_list_get_head_raw(struct exec_list *list)
389 {
390    return list->head_sentinel.next;
391 }
392 
393 static inline const struct exec_node *
exec_list_get_tail_const(const struct exec_list * list)394 exec_list_get_tail_const(const struct exec_list *list)
395 {
396    return !exec_list_is_empty(list) ? list->tail_sentinel.prev : NULL;
397 }
398 
399 static inline struct exec_node *
exec_list_get_tail(struct exec_list * list)400 exec_list_get_tail(struct exec_list *list)
401 {
402    return !exec_list_is_empty(list) ? list->tail_sentinel.prev : NULL;
403 }
404 
405 static inline const struct exec_node *
exec_list_get_tail_raw_const(const struct exec_list * list)406 exec_list_get_tail_raw_const(const struct exec_list *list)
407 {
408    return list->tail_sentinel.prev;
409 }
410 
411 static inline struct exec_node *
exec_list_get_tail_raw(struct exec_list * list)412 exec_list_get_tail_raw(struct exec_list *list)
413 {
414    return list->tail_sentinel.prev;
415 }
416 
417 static inline unsigned
exec_list_length(const struct exec_list * list)418 exec_list_length(const struct exec_list *list)
419 {
420    unsigned size = 0;
421    struct exec_node *node;
422 
423    for (node = list->head_sentinel.next; node->next != NULL; node = node->next) {
424       size++;
425    }
426 
427    return size;
428 }
429 
430 static inline void
exec_list_push_head(struct exec_list * list,struct exec_node * n)431 exec_list_push_head(struct exec_list *list, struct exec_node *n)
432 {
433    n->next = list->head_sentinel.next;
434    n->prev = &list->head_sentinel;
435 
436    n->next->prev = n;
437    list->head_sentinel.next = n;
438 }
439 
440 static inline void
exec_list_push_tail(struct exec_list * list,struct exec_node * n)441 exec_list_push_tail(struct exec_list *list, struct exec_node *n)
442 {
443    n->next = &list->tail_sentinel;
444    n->prev = list->tail_sentinel.prev;
445 
446    n->prev->next = n;
447    list->tail_sentinel.prev = n;
448 }
449 
450 static inline void
exec_list_push_degenerate_list_at_head(struct exec_list * list,struct exec_node * n)451 exec_list_push_degenerate_list_at_head(struct exec_list *list, struct exec_node *n)
452 {
453    assert(n->prev->next == n);
454 
455    n->prev->next = list->head_sentinel.next;
456    list->head_sentinel.next->prev = n->prev;
457    n->prev = &list->head_sentinel;
458    list->head_sentinel.next = n;
459 }
460 
461 static inline struct exec_node *
exec_list_pop_head(struct exec_list * list)462 exec_list_pop_head(struct exec_list *list)
463 {
464    struct exec_node *const n = exec_list_get_head(list);
465    if (n != NULL)
466       exec_node_remove(n);
467 
468    return n;
469 }
470 
471 static inline void
exec_list_move_nodes_to(struct exec_list * list,struct exec_list * target)472 exec_list_move_nodes_to(struct exec_list *list, struct exec_list *target)
473 {
474    if (exec_list_is_empty(list)) {
475       exec_list_make_empty(target);
476    } else {
477       target->head_sentinel.next = list->head_sentinel.next;
478       target->head_sentinel.prev = NULL;
479       target->tail_sentinel.next = NULL;
480       target->tail_sentinel.prev = list->tail_sentinel.prev;
481 
482       target->head_sentinel.next->prev = &target->head_sentinel;
483       target->tail_sentinel.prev->next = &target->tail_sentinel;
484 
485       exec_list_make_empty(list);
486    }
487 }
488 
489 static inline void
exec_list_append(struct exec_list * list,struct exec_list * source)490 exec_list_append(struct exec_list *list, struct exec_list *source)
491 {
492    if (exec_list_is_empty(source))
493       return;
494 
495    /* Link the first node of the source with the last node of the target list.
496     */
497    list->tail_sentinel.prev->next = source->head_sentinel.next;
498    source->head_sentinel.next->prev = list->tail_sentinel.prev;
499 
500    /* Make the tail of the source list be the tail of the target list.
501     */
502    list->tail_sentinel.prev = source->tail_sentinel.prev;
503    list->tail_sentinel.prev->next = &list->tail_sentinel;
504 
505    /* Make the source list empty for good measure.
506     */
507    exec_list_make_empty(source);
508 }
509 
510 static inline void
exec_list_prepend(struct exec_list * list,struct exec_list * source)511 exec_list_prepend(struct exec_list *list, struct exec_list *source)
512 {
513    exec_list_append(source, list);
514    exec_list_move_nodes_to(source, list);
515 }
516 
517 static inline void
exec_node_insert_list_before(struct exec_node * n,struct exec_list * before)518 exec_node_insert_list_before(struct exec_node *n, struct exec_list *before)
519 {
520    if (exec_list_is_empty(before))
521       return;
522 
523    before->tail_sentinel.prev->next = n;
524    before->head_sentinel.next->prev = n->prev;
525 
526    n->prev->next = before->head_sentinel.next;
527    n->prev = before->tail_sentinel.prev;
528 
529    exec_list_make_empty(before);
530 }
531 
532 static inline void
exec_list_validate(const struct exec_list * list)533 exec_list_validate(const struct exec_list *list)
534 {
535    const struct exec_node *node;
536 
537    assert(list->head_sentinel.next->prev == &list->head_sentinel);
538    assert(list->head_sentinel.prev == NULL);
539    assert(list->tail_sentinel.next == NULL);
540    assert(list->tail_sentinel.prev->next == &list->tail_sentinel);
541 
542    /* We could try to use one of the interators below for this but they all
543     * either require C++ or assume the exec_node is embedded in a structure
544     * which is not the case for this function.
545     */
546    for (node = list->head_sentinel.next; node->next != NULL; node = node->next) {
547       assert(node->next->prev == node);
548       assert(node->prev->next == node);
549    }
550 }
551 
552 #ifdef __cplusplus
make_empty()553 inline void exec_list::make_empty()
554 {
555    exec_list_make_empty(this);
556 }
557 
is_empty()558 inline bool exec_list::is_empty() const
559 {
560    return exec_list_is_empty(this);
561 }
562 
get_head()563 inline const exec_node *exec_list::get_head() const
564 {
565    return exec_list_get_head_const(this);
566 }
567 
get_head()568 inline exec_node *exec_list::get_head()
569 {
570    return exec_list_get_head(this);
571 }
572 
get_head_raw()573 inline const exec_node *exec_list::get_head_raw() const
574 {
575    return exec_list_get_head_raw_const(this);
576 }
577 
get_head_raw()578 inline exec_node *exec_list::get_head_raw()
579 {
580    return exec_list_get_head_raw(this);
581 }
582 
get_tail()583 inline const exec_node *exec_list::get_tail() const
584 {
585    return exec_list_get_tail_const(this);
586 }
587 
get_tail()588 inline exec_node *exec_list::get_tail()
589 {
590    return exec_list_get_tail(this);
591 }
592 
get_tail_raw()593 inline const exec_node *exec_list::get_tail_raw() const
594 {
595    return exec_list_get_tail_raw_const(this);
596 }
597 
get_tail_raw()598 inline exec_node *exec_list::get_tail_raw()
599 {
600    return exec_list_get_tail_raw(this);
601 }
602 
length()603 inline unsigned exec_list::length() const
604 {
605    return exec_list_length(this);
606 }
607 
push_head(exec_node * n)608 inline void exec_list::push_head(exec_node *n)
609 {
610    exec_list_push_head(this, n);
611 }
612 
push_tail(exec_node * n)613 inline void exec_list::push_tail(exec_node *n)
614 {
615    exec_list_push_tail(this, n);
616 }
617 
push_degenerate_list_at_head(exec_node * n)618 inline void exec_list::push_degenerate_list_at_head(exec_node *n)
619 {
620    exec_list_push_degenerate_list_at_head(this, n);
621 }
622 
pop_head()623 inline exec_node *exec_list::pop_head()
624 {
625    return exec_list_pop_head(this);
626 }
627 
move_nodes_to(exec_list * target)628 inline void exec_list::move_nodes_to(exec_list *target)
629 {
630    exec_list_move_nodes_to(this, target);
631 }
632 
append_list(exec_list * source)633 inline void exec_list::append_list(exec_list *source)
634 {
635    exec_list_append(this, source);
636 }
637 
prepend_list(exec_list * source)638 inline void exec_list::prepend_list(exec_list *source)
639 {
640    exec_list_prepend(this, source);
641 }
642 
insert_before(exec_list * before)643 inline void exec_node::insert_before(exec_list *before)
644 {
645    exec_node_insert_list_before(this, before);
646 }
647 #endif
648 
649 #define foreach_in_list(__type, __inst, __list)      \
650    for (__type *(__inst) = (__type *)(__list)->head_sentinel.next; \
651         !(__inst)->is_tail_sentinel();               \
652         (__inst) = (__type *)(__inst)->next)
653 
654 #define foreach_in_list_reverse(__type, __inst, __list)   \
655    for (__type *(__inst) = (__type *)(__list)->tail_sentinel.prev; \
656         !(__inst)->is_head_sentinel();                    \
657         (__inst) = (__type *)(__inst)->prev)
658 
659 /**
660  * This version is safe even if the current node is removed.
661  */
662 #define foreach_in_list_safe(__type, __node, __list) \
663    for (__type *__node = (__type *)(__list)->head_sentinel.next,   \
664                *__next = (__type *)__node->next;     \
665         __next != NULL;                              \
666         __node = __next, __next = (__type *)__next->next)
667 
668 #define foreach_in_list_reverse_safe(__type, __node, __list) \
669    for (__type *__node = (__type *)(__list)->tail_sentinel.prev,      \
670                *__prev = (__type *)__node->prev;             \
671         __prev != NULL;                                      \
672         __node = __prev, __prev = (__type *)__prev->prev)
673 
674 #define foreach_in_list_use_after(__type, __inst, __list) \
675    __type *(__inst);                                      \
676    for ((__inst) = (__type *)(__list)->head_sentinel.next; \
677         !(__inst)->is_tail_sentinel();                    \
678         (__inst) = (__type *)(__inst)->next)
679 /**
680  * Iterate through two lists at once.  Stops at the end of the shorter list.
681  *
682  * This is safe against either current node being removed or replaced.
683  */
684 #define foreach_two_lists(__node1, __list1, __node2, __list2) \
685    for (struct exec_node * __node1 = (__list1)->head_sentinel.next, \
686                          * __node2 = (__list2)->head_sentinel.next, \
687                          * __next1 = __node1->next,           \
688                          * __next2 = __node2->next            \
689 	; __next1 != NULL && __next2 != NULL                  \
690 	; __node1 = __next1,                                  \
691           __node2 = __next2,                                  \
692           __next1 = __next1->next,                            \
693           __next2 = __next2->next)
694 
695 #define foreach_list_typed(__type, __node, __field, __list)		\
696    for (__type * __node =						\
697          exec_node_data(__type, (__list)->head_sentinel.next, __field); \
698 	(__node)->__field.next != NULL; 				\
699 	(__node) = exec_node_data(__type, (__node)->__field.next, __field))
700 
701 #define foreach_list_typed_from(__type, __node, __field, __list, __start)  \
702    for (__type * __node = exec_node_data(__type, (__start), __field);      \
703 	(__node)->__field.next != NULL;                                    \
704 	(__node) = exec_node_data(__type, (__node)->__field.next, __field))
705 
706 #define foreach_list_typed_reverse(__type, __node, __field, __list)        \
707    for (__type * __node =                                                \
708            exec_node_data(__type, (__list)->tail_sentinel.prev, __field);  \
709         (__node)->__field.prev != NULL;                                 \
710         (__node) = exec_node_data(__type, (__node)->__field.prev, __field))
711 
712 #define foreach_list_typed_safe(__type, __node, __field, __list)           \
713    for (__type * __node =                                                  \
714            exec_node_data(__type, (__list)->head_sentinel.next, __field),  \
715                * __next =                                                  \
716            exec_node_data(__type, (__node)->__field.next, __field);        \
717         (__node)->__field.next != NULL;                                    \
718         __node = __next, __next =                                          \
719            exec_node_data(__type, (__next)->__field.next, __field))
720 
721 #define foreach_list_typed_reverse_safe(__type, __node, __field, __list)   \
722    for (__type * __node =                                                  \
723            exec_node_data(__type, (__list)->tail_sentinel.prev, __field),  \
724                * __prev =                                                  \
725            exec_node_data(__type, (__node)->__field.prev, __field);        \
726         (__node)->__field.prev != NULL;                                    \
727         __node = __prev, __prev =                                          \
728            exec_node_data(__type, (__prev)->__field.prev, __field))
729 
730 #endif /* LIST_CONTAINER_H */
731