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