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