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