Subversion Repositories Kolibri OS

Rev

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

  1. /**************************************************************************
  2.  *
  3.  * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
  4.  * All Rights Reserved.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the
  8.  * "Software"), to deal in the Software without restriction, including
  9.  * without limitation the rights to use, copy, modify, merge, publish,
  10.  * distribute, sub license, and/or sell copies of the Software, and to
  11.  * permit persons to whom the Software is furnished to do so, subject to
  12.  * the following conditions:
  13.  *
  14.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  17.  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  18.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  19.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  20.  * USE OR OTHER DEALINGS IN THE SOFTWARE.
  21.  *
  22.  * The above copyright notice and this permission notice (including the
  23.  * next paragraph) shall be included in all copies or substantial portions
  24.  * of the Software.
  25.  *
  26.  **************************************************************************/
  27.  
  28. /**
  29.  * \file
  30.  * List macros heavily inspired by the Linux kernel
  31.  * list handling. No list looping yet.
  32.  *
  33.  * Is not threadsafe, so common operations need to
  34.  * be protected using an external mutex.
  35.  */
  36.  
  37. #ifndef _U_DOUBLE_LIST_H_
  38. #define _U_DOUBLE_LIST_H_
  39.  
  40.  
  41. #include <stddef.h>
  42. #include "pipe/p_compiler.h"
  43.  
  44.  
  45. struct list_head
  46. {
  47.     struct list_head *prev;
  48.     struct list_head *next;
  49. };
  50.  
  51. static INLINE void list_inithead(struct list_head *item)
  52. {
  53.     item->prev = item;
  54.     item->next = item;
  55. }
  56.  
  57. static INLINE void list_add(struct list_head *item, struct list_head *list)
  58. {
  59.     item->prev = list;
  60.     item->next = list->next;
  61.     list->next->prev = item;
  62.     list->next = item;
  63. }
  64.  
  65. static INLINE void list_addtail(struct list_head *item, struct list_head *list)
  66. {
  67.     item->next = list;
  68.     item->prev = list->prev;
  69.     list->prev->next = item;
  70.     list->prev = item;
  71. }
  72.  
  73. static INLINE void list_replace(struct list_head *from, struct list_head *to)
  74. {
  75.     to->prev = from->prev;
  76.     to->next = from->next;
  77.     from->next->prev = to;
  78.     from->prev->next = to;
  79. }
  80.  
  81. static INLINE void list_del(struct list_head *item)
  82. {
  83.     item->prev->next = item->next;
  84.     item->next->prev = item->prev;
  85.     item->prev = item->next = NULL;
  86. }
  87.  
  88. static INLINE void list_delinit(struct list_head *item)
  89. {
  90.     item->prev->next = item->next;
  91.     item->next->prev = item->prev;
  92.     item->next = item;
  93.     item->prev = item;
  94. }
  95.  
  96. #define LIST_INITHEAD(__item) list_inithead(__item)
  97. #define LIST_ADD(__item, __list) list_add(__item, __list)
  98. #define LIST_ADDTAIL(__item, __list) list_addtail(__item, __list)
  99. #define LIST_REPLACE(__from, __to) list_replace(__from, __to)
  100. #define LIST_DEL(__item) list_del(__item)
  101. #define LIST_DELINIT(__item) list_delinit(__item)
  102.  
  103. #define LIST_ENTRY(__type, __item, __field)   \
  104.     ((__type *)(((char *)(__item)) - offsetof(__type, __field)))
  105.  
  106. #define LIST_IS_EMPTY(__list)                   \
  107.     ((__list)->next == (__list))
  108.  
  109. /**
  110.  * Cast from a pointer to a member of a struct back to the containing struct.
  111.  *
  112.  * 'sample' MUST be initialized, or else the result is undefined!
  113.  */
  114. #ifndef container_of
  115. #define container_of(ptr, sample, member)                               \
  116.     (void *)((char *)(ptr)                                              \
  117.              - ((char *)&(sample)->member - (char *)(sample)))
  118. #endif
  119.  
  120. #define LIST_FOR_EACH_ENTRY(pos, head, member)                          \
  121.    for (pos = NULL, pos = container_of((head)->next, pos, member);      \
  122.         &pos->member != (head);                                         \
  123.         pos = container_of(pos->member.next, pos, member))
  124.  
  125. #define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member)    \
  126.    for (pos = NULL, pos = container_of((head)->next, pos, member),      \
  127.         storage = container_of(pos->member.next, pos, member);  \
  128.         &pos->member != (head);                                         \
  129.         pos = storage, storage = container_of(storage->member.next, storage, member))
  130.  
  131. #define LIST_FOR_EACH_ENTRY_SAFE_REV(pos, storage, head, member)        \
  132.    for (pos = NULL, pos = container_of((head)->prev, pos, member),      \
  133.         storage = container_of(pos->member.prev, pos, member);          \
  134.         &pos->member != (head);                                         \
  135.         pos = storage, storage = container_of(storage->member.prev, storage, member))
  136.  
  137. #define LIST_FOR_EACH_ENTRY_FROM(pos, start, head, member)              \
  138.    for (pos = NULL, pos = container_of((start), pos, member);           \
  139.         &pos->member != (head);                                         \
  140.         pos = container_of(pos->member.next, pos, member))
  141.  
  142. #define LIST_FOR_EACH_ENTRY_FROM_REV(pos, start, head, member)          \
  143.    for (pos = NULL, pos = container_of((start), pos, member);           \
  144.         &pos->member != (head);                                         \
  145.         pos = container_of(pos->member.prev, pos, member))
  146.  
  147. #endif /*_U_DOUBLE_LIST_H_*/
  148.