Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright © 2010-2012 Intel Corporation
  3.  * Copyright © 2010 Francisco Jerez <currojerez@riseup.net>
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining a
  6.  * copy of this software and associated documentation files (the "Software"),
  7.  * to deal in the Software without restriction, including without limitation
  8.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  9.  * and/or sell copies of the Software, and to permit persons to whom the
  10.  * Software is furnished to do so, subject to the following conditions:
  11.  *
  12.  * The above copyright notice and this permission notice (including the next
  13.  * paragraph) shall be included in all copies or substantial portions of the
  14.  * Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  22.  * IN THE SOFTWARE.
  23.  *
  24.  */
  25.  
  26. #ifndef _INTEL_LIST_H_
  27. #define _INTEL_LIST_H_
  28.  
  29. #include <stdbool.h>
  30.  
  31. /**
  32.  * @file Classic doubly-link circular list implementation.
  33.  * For real usage examples of the linked list, see the file test/list.c
  34.  *
  35.  * Example:
  36.  * We need to keep a list of struct foo in the parent struct bar, i.e. what
  37.  * we want is something like this.
  38.  *
  39.  *     struct bar {
  40.  *          ...
  41.  *          struct foo *list_of_foos; -----> struct foo {}, struct foo {}, struct foo{}
  42.  *          ...
  43.  *     }
  44.  *
  45.  * We need one list head in bar and a list element in all list_of_foos (both are of
  46.  * data type 'struct list').
  47.  *
  48.  *     struct bar {
  49.  *          ...
  50.  *          struct list list_of_foos;
  51.  *          ...
  52.  *     }
  53.  *
  54.  *     struct foo {
  55.  *          ...
  56.  *          struct list entry;
  57.  *          ...
  58.  *     }
  59.  *
  60.  * Now we initialize the list head:
  61.  *
  62.  *     struct bar bar;
  63.  *     ...
  64.  *     list_init(&bar.list_of_foos);
  65.  *
  66.  * Then we create the first element and add it to this list:
  67.  *
  68.  *     struct foo *foo = malloc(...);
  69.  *     ....
  70.  *     list_add(&foo->entry, &bar.list_of_foos);
  71.  *
  72.  * Repeat the above for each element you want to add to the list. Deleting
  73.  * works with the element itself.
  74.  *      list_del(&foo->entry);
  75.  *      free(foo);
  76.  *
  77.  * Note: calling list_del(&bar.list_of_foos) will set bar.list_of_foos to an empty
  78.  * list again.
  79.  *
  80.  * Looping through the list requires a 'struct foo' as iterator and the
  81.  * name of the field the subnodes use.
  82.  *
  83.  * struct foo *iterator;
  84.  * list_for_each_entry(iterator, &bar.list_of_foos, entry) {
  85.  *      if (iterator->something == ...)
  86.  *             ...
  87.  * }
  88.  *
  89.  * Note: You must not call list_del() on the iterator if you continue the
  90.  * loop. You need to run the safe for-each loop instead:
  91.  *
  92.  * struct foo *iterator, *next;
  93.  * list_for_each_entry_safe(iterator, next, &bar.list_of_foos, entry) {
  94.  *      if (...)
  95.  *              list_del(&iterator->entry);
  96.  * }
  97.  *
  98.  */
  99.  
  100. /**
  101.  * The linkage struct for list nodes. This struct must be part of your
  102.  * to-be-linked struct. struct list is required for both the head of the
  103.  * list and for each list node.
  104.  *
  105.  * Position and name of the struct list field is irrelevant.
  106.  * There are no requirements that elements of a list are of the same type.
  107.  * There are no requirements for a list head, any struct list can be a list
  108.  * head.
  109.  */
  110. struct list {
  111.     struct list *next, *prev;
  112. };
  113.  
  114. /**
  115.  * Initialize the list as an empty list.
  116.  *
  117.  * Example:
  118.  * list_init(&bar->list_of_foos);
  119.  *
  120.  * @param The list to initialized.
  121.  */
  122. static void
  123. list_init(struct list *list)
  124. {
  125.     list->next = list->prev = list;
  126. }
  127.  
  128. static inline void
  129. __list_add(struct list *entry,
  130.             struct list *prev,
  131.             struct list *next)
  132. {
  133.     next->prev = entry;
  134.     entry->next = next;
  135.     entry->prev = prev;
  136.     prev->next = entry;
  137. }
  138.  
  139. /**
  140.  * Insert a new element after the given list head. The new element does not
  141.  * need to be initialised as empty list.
  142.  * The list changes from:
  143.  *      head → some element → ...
  144.  * to
  145.  *      head → new element → older element → ...
  146.  *
  147.  * Example:
  148.  * struct foo *newfoo = malloc(...);
  149.  * list_add(&newfoo->entry, &bar->list_of_foos);
  150.  *
  151.  * @param entry The new element to prepend to the list.
  152.  * @param head The existing list.
  153.  */
  154. static inline void
  155. list_add(struct list *entry, struct list *head)
  156. {
  157.     __list_add(entry, head, head->next);
  158. }
  159.  
  160. static inline void
  161. list_add_tail(struct list *entry, struct list *head)
  162. {
  163.     __list_add(entry, head->prev, head);
  164. }
  165.  
  166. static inline void list_replace(struct list *old,
  167.                                 struct list *new)
  168. {
  169.         new->next = old->next;
  170.         new->next->prev = new;
  171.         new->prev = old->prev;
  172.         new->prev->next = new;
  173. }
  174.  
  175. #define list_last_entry(ptr, type, member) \
  176.     list_entry((ptr)->prev, type, member)
  177.  
  178. #define list_for_each(pos, head)                                \
  179.     for (pos = (head)->next; pos != (head); pos = pos->next)
  180.  
  181. /**
  182.  * Append a new element to the end of the list given with this list head.
  183.  *
  184.  * The list changes from:
  185.  *      head → some element → ... → lastelement
  186.  * to
  187.  *      head → some element → ... → lastelement → new element
  188.  *
  189.  * Example:
  190.  * struct foo *newfoo = malloc(...);
  191.  * list_append(&newfoo->entry, &bar->list_of_foos);
  192.  *
  193.  * @param entry The new element to prepend to the list.
  194.  * @param head The existing list.
  195.  */
  196. static inline void
  197. list_append(struct list *entry, struct list *head)
  198. {
  199.     __list_add(entry, head->prev, head);
  200. }
  201.  
  202.  
  203. static inline void
  204. __list_del(struct list *prev, struct list *next)
  205. {
  206.         assert(next->prev == prev->next);
  207.         next->prev = prev;
  208.         prev->next = next;
  209. }
  210.  
  211. static inline void
  212. _list_del(struct list *entry)
  213. {
  214.     assert(entry->prev->next == entry);
  215.     assert(entry->next->prev == entry);
  216.     __list_del(entry->prev, entry->next);
  217. }
  218.  
  219. /**
  220.  * Remove the element from the list it is in. Using this function will reset
  221.  * the pointers to/from this element so it is removed from the list. It does
  222.  * NOT free the element itself or manipulate it otherwise.
  223.  *
  224.  * Using list_del on a pure list head (like in the example at the top of
  225.  * this file) will NOT remove the first element from
  226.  * the list but rather reset the list as empty list.
  227.  *
  228.  * Example:
  229.  * list_del(&foo->entry);
  230.  *
  231.  * @param entry The element to remove.
  232.  */
  233. static inline void
  234. list_del(struct list *entry)
  235. {
  236.     _list_del(entry);
  237.     list_init(entry);
  238. }
  239.  
  240. static inline void list_move(struct list *list, struct list *head)
  241. {
  242.         if (list->prev != head) {
  243.                 _list_del(list);
  244.                 list_add(list, head);
  245.         }
  246. }
  247.  
  248. static inline void list_move_tail(struct list *list, struct list *head)
  249. {
  250.         _list_del(list);
  251.         list_add_tail(list, head);
  252. }
  253.  
  254. /**
  255.  * Check if the list is empty.
  256.  *
  257.  * Example:
  258.  * list_is_empty(&bar->list_of_foos);
  259.  *
  260.  * @return True if the list contains one or more elements or False otherwise.
  261.  */
  262. static inline bool
  263. list_is_empty(struct list *head)
  264. {
  265.     return head->next == head;
  266. }
  267.  
  268. /**
  269.  * Alias of container_of
  270.  */
  271. #define list_entry(ptr, type, member) \
  272.     container_of(ptr, type, member)
  273.  
  274. /**
  275.  * Retrieve the first list entry for the given list pointer.
  276.  *
  277.  * Example:
  278.  * struct foo *first;
  279.  * first = list_first_entry(&bar->list_of_foos, struct foo, list_of_foos);
  280.  *
  281.  * @param ptr The list head
  282.  * @param type Data type of the list element to retrieve
  283.  * @param member Member name of the struct list field in the list element.
  284.  * @return A pointer to the first list element.
  285.  */
  286. #define list_first_entry(ptr, type, member) \
  287.     list_entry((ptr)->next, type, member)
  288.  
  289. /**
  290.  * Retrieve the last list entry for the given listpointer.
  291.  *
  292.  * Example:
  293.  * struct foo *first;
  294.  * first = list_last_entry(&bar->list_of_foos, struct foo, list_of_foos);
  295.  *
  296.  * @param ptr The list head
  297.  * @param type Data type of the list element to retrieve
  298.  * @param member Member name of the struct list field in the list element.
  299.  * @return A pointer to the last list element.
  300.  */
  301. #define list_last_entry(ptr, type, member) \
  302.     list_entry((ptr)->prev, type, member)
  303.  
  304. #define __container_of(ptr, sample, member)                             \
  305.     (void *)((char *)(ptr)                                              \
  306.              - ((char *)&(sample)->member - (char *)(sample)))
  307. /**
  308.  * Loop through the list given by head and set pos to struct in the list.
  309.  *
  310.  * Example:
  311.  * struct foo *iterator;
  312.  * list_for_each_entry(iterator, &bar->list_of_foos, entry) {
  313.  *      [modify iterator]
  314.  * }
  315.  *
  316.  * This macro is not safe for node deletion. Use list_for_each_entry_safe
  317.  * instead.
  318.  *
  319.  * @param pos Iterator variable of the type of the list elements.
  320.  * @param head List head
  321.  * @param member Member name of the struct list in the list elements.
  322.  *
  323.  */
  324. #define list_for_each_entry(pos, head, member)                          \
  325.     for (pos = __container_of((head)->next, pos, member);               \
  326.          &pos->member != (head);                                        \
  327.          pos = __container_of(pos->member.next, pos, member))
  328.  
  329. #define list_for_each_entry_reverse(pos, head, member)                          \
  330.     for (pos = __container_of((head)->prev, pos, member);               \
  331.          &pos->member != (head);                                        \
  332.          pos = __container_of(pos->member.prev, pos, member))
  333.  
  334. /**
  335.  * Loop through the list, keeping a backup pointer to the element. This
  336.  * macro allows for the deletion of a list element while looping through the
  337.  * list.
  338.  *
  339.  * See list_for_each_entry for more details.
  340.  */
  341. #define list_for_each_entry_safe(pos, tmp, head, member)                \
  342.     for (pos = __container_of((head)->next, pos, member),               \
  343.          tmp = __container_of(pos->member.next, pos, member);           \
  344.          &pos->member != (head);                                        \
  345.          pos = tmp, tmp = __container_of(pos->member.next, tmp, member))
  346.  
  347.  
  348. #undef container_of
  349. #define container_of(ptr, type, member) \
  350.         ((type *)((char *)(ptr) - (char *) &((type *)0)->member))
  351.  
  352. #endif /* _INTEL_LIST_H_ */
  353.  
  354.