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