Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 1991, 1993
  3.  *      The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *      This product includes software developed by the University of
  16.  *      California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  *      @(#)queue.h     8.5 (Berkeley) 8/20/94
  34.  * $FreeBSD: src/sys/sys/queue.h,v 1.48 2002/04/17 14:00:37 tmm Exp $
  35.  */
  36.  
  37. #ifndef _SYS_QUEUE_H_
  38. #define _SYS_QUEUE_H_
  39.  
  40. #include <machine/ansi.h>       /* for __offsetof */
  41.  
  42. /*
  43.  * This file defines four types of data structures: singly-linked lists,
  44.  * singly-linked tail queues, lists and tail queues.
  45.  *
  46.  * A singly-linked list is headed by a single forward pointer. The elements
  47.  * are singly linked for minimum space and pointer manipulation overhead at
  48.  * the expense of O(n) removal for arbitrary elements. New elements can be
  49.  * added to the list after an existing element or at the head of the list.
  50.  * Elements being removed from the head of the list should use the explicit
  51.  * macro for this purpose for optimum efficiency. A singly-linked list may
  52.  * only be traversed in the forward direction.  Singly-linked lists are ideal
  53.  * for applications with large datasets and few or no removals or for
  54.  * implementing a LIFO queue.
  55.  *
  56.  * A singly-linked tail queue is headed by a pair of pointers, one to the
  57.  * head of the list and the other to the tail of the list. The elements are
  58.  * singly linked for minimum space and pointer manipulation overhead at the
  59.  * expense of O(n) removal for arbitrary elements. New elements can be added
  60.  * to the list after an existing element, at the head of the list, or at the
  61.  * end of the list. Elements being removed from the head of the tail queue
  62.  * should use the explicit macro for this purpose for optimum efficiency.
  63.  * A singly-linked tail queue may only be traversed in the forward direction.
  64.  * Singly-linked tail queues are ideal for applications with large datasets
  65.  * and few or no removals or for implementing a FIFO queue.
  66.  *
  67.  * A list is headed by a single forward pointer (or an array of forward
  68.  * pointers for a hash table header). The elements are doubly linked
  69.  * so that an arbitrary element can be removed without a need to
  70.  * traverse the list. New elements can be added to the list before
  71.  * or after an existing element or at the head of the list. A list
  72.  * may only be traversed in the forward direction.
  73.  *
  74.  * A tail queue is headed by a pair of pointers, one to the head of the
  75.  * list and the other to the tail of the list. The elements are doubly
  76.  * linked so that an arbitrary element can be removed without a need to
  77.  * traverse the list. New elements can be added to the list before or
  78.  * after an existing element, at the head of the list, or at the end of
  79.  * the list. A tail queue may be traversed in either direction.
  80.  *
  81.  * For details on the use of these macros, see the queue(3) manual page.
  82.  *
  83.  *
  84.  *                      SLIST   LIST    STAILQ  TAILQ
  85.  * _HEAD                +       +       +       +
  86.  * _HEAD_INITIALIZER    +       +       +       +
  87.  * _ENTRY               +       +       +       +
  88.  * _INIT                +       +       +       +
  89.  * _EMPTY               +       +       +       +
  90.  * _FIRST               +       +       +       +
  91.  * _NEXT                +       +       +       +
  92.  * _PREV                -       -       -       +
  93.  * _LAST                -       -       +       +
  94.  * _FOREACH             +       +       +       +
  95.  * _FOREACH_REVERSE     -       -       -       +
  96.  * _INSERT_HEAD         +       +       +       +
  97.  * _INSERT_BEFORE       -       +       -       +
  98.  * _INSERT_AFTER        +       +       +       +
  99.  * _INSERT_TAIL         -       -       +       +
  100.  * _CONCAT              -       -       +       +
  101.  * _REMOVE_HEAD         +       -       +       -
  102.  * _REMOVE              +       +       +       +
  103.  *
  104.  */
  105.  
  106. /*
  107.  * Singly-linked List declarations.
  108.  */
  109. #define SLIST_HEAD(name, type)                                          \
  110. struct name {                                                           \
  111.         struct type *slh_first; /* first element */                     \
  112. }
  113.  
  114. #define SLIST_HEAD_INITIALIZER(head)                                    \
  115.         { NULL }
  116.  
  117. #define SLIST_ENTRY(type)                                               \
  118. struct {                                                                \
  119.         struct type *sle_next;  /* next element */                      \
  120. }
  121.  
  122. /*
  123.  * Singly-linked List functions.
  124.  */
  125. #define SLIST_EMPTY(head)       ((head)->slh_first == NULL)
  126.  
  127. #define SLIST_FIRST(head)       ((head)->slh_first)
  128.  
  129. #define SLIST_FOREACH(var, head, field)                                 \
  130.         for ((var) = SLIST_FIRST((head));                               \
  131.             (var);                                                      \
  132.             (var) = SLIST_NEXT((var), field))
  133.  
  134. #define SLIST_INIT(head) do {                                           \
  135.         SLIST_FIRST((head)) = NULL;                                     \
  136. } while (0)
  137.  
  138. #define SLIST_INSERT_AFTER(slistelm, elm, field) do {                   \
  139.         SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);       \
  140.         SLIST_NEXT((slistelm), field) = (elm);                          \
  141. } while (0)
  142.  
  143. #define SLIST_INSERT_HEAD(head, elm, field) do {                        \
  144.         SLIST_NEXT((elm), field) = SLIST_FIRST((head));                 \
  145.         SLIST_FIRST((head)) = (elm);                                    \
  146. } while (0)
  147.  
  148. #define SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
  149.  
  150. #define SLIST_REMOVE(head, elm, type, field) do {                       \
  151.         if (SLIST_FIRST((head)) == (elm)) {                             \
  152.                 SLIST_REMOVE_HEAD((head), field);                       \
  153.         }                                                               \
  154.         else {                                                          \
  155.                 struct type *curelm = SLIST_FIRST((head));              \
  156.                 while (SLIST_NEXT(curelm, field) != (elm))              \
  157.                         curelm = SLIST_NEXT(curelm, field);             \
  158.                 SLIST_NEXT(curelm, field) =                             \
  159.                     SLIST_NEXT(SLIST_NEXT(curelm, field), field);       \
  160.         }                                                               \
  161. } while (0)
  162.  
  163. #define SLIST_REMOVE_HEAD(head, field) do {                             \
  164.         SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);   \
  165. } while (0)
  166.  
  167. /*
  168.  * Singly-linked Tail queue declarations.
  169.  */
  170. #define STAILQ_HEAD(name, type)                                         \
  171. struct name {                                                           \
  172.         struct type *stqh_first;/* first element */                     \
  173.         struct type **stqh_last;/* addr of last next element */         \
  174. }
  175.  
  176. #define STAILQ_HEAD_INITIALIZER(head)                                   \
  177.         { NULL, &(head).stqh_first }
  178.  
  179. #define STAILQ_ENTRY(type)                                              \
  180. struct {                                                                \
  181.         struct type *stqe_next; /* next element */                      \
  182. }
  183.  
  184. /*
  185.  * Singly-linked Tail queue functions.
  186.  */
  187. #define STAILQ_CONCAT(head1, head2) do {                                \
  188.         if (!STAILQ_EMPTY((head2))) {                                   \
  189.                 *(head1)->stqh_last = (head2)->stqh_first;              \
  190.                 (head1)->stqh_last = (head2)->stqh_last;                \
  191.                 STAILQ_INIT((head2));                                   \
  192.         }                                                               \
  193. } while (0)
  194.  
  195. #define STAILQ_EMPTY(head)      ((head)->stqh_first == NULL)
  196.  
  197. #define STAILQ_FIRST(head)      ((head)->stqh_first)
  198.  
  199. #define STAILQ_FOREACH(var, head, field)                                \
  200.         for((var) = STAILQ_FIRST((head));                               \
  201.            (var);                                                       \
  202.            (var) = STAILQ_NEXT((var), field))
  203.  
  204. #define STAILQ_INIT(head) do {                                          \
  205.         STAILQ_FIRST((head)) = NULL;                                    \
  206.         (head)->stqh_last = &STAILQ_FIRST((head));                      \
  207. } while (0)
  208.  
  209. #define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {               \
  210.         if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
  211.                 (head)->stqh_last = &STAILQ_NEXT((elm), field);         \
  212.         STAILQ_NEXT((tqelm), field) = (elm);                            \
  213. } while (0)
  214.  
  215. #define STAILQ_INSERT_HEAD(head, elm, field) do {                       \
  216.         if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
  217.                 (head)->stqh_last = &STAILQ_NEXT((elm), field);         \
  218.         STAILQ_FIRST((head)) = (elm);                                   \
  219. } while (0)
  220.  
  221. #define STAILQ_INSERT_TAIL(head, elm, field) do {                       \
  222.         STAILQ_NEXT((elm), field) = NULL;                               \
  223.         *(head)->stqh_last = (elm);                                     \
  224.         (head)->stqh_last = &STAILQ_NEXT((elm), field);                 \
  225. } while (0)
  226.  
  227. #define STAILQ_LAST(head, type, field)                                  \
  228.         (STAILQ_EMPTY((head)) ?                                         \
  229.                 NULL :                                                  \
  230.                 ((struct type *)                                        \
  231.                 ((char *)((head)->stqh_last) - __offsetof(struct type, field))))
  232.  
  233. #define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
  234.  
  235. #define STAILQ_REMOVE(head, elm, type, field) do {                      \
  236.         if (STAILQ_FIRST((head)) == (elm)) {                            \
  237.                 STAILQ_REMOVE_HEAD((head), field);                      \
  238.         }                                                               \
  239.         else {                                                          \
  240.                 struct type *curelm = STAILQ_FIRST((head));             \
  241.                 while (STAILQ_NEXT(curelm, field) != (elm))             \
  242.                         curelm = STAILQ_NEXT(curelm, field);            \
  243.                 if ((STAILQ_NEXT(curelm, field) =                       \
  244.                      STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
  245.                         (head)->stqh_last = &STAILQ_NEXT((curelm), field);\
  246.         }                                                               \
  247. } while (0)
  248.  
  249. #define STAILQ_REMOVE_HEAD(head, field) do {                            \
  250.         if ((STAILQ_FIRST((head)) =                                     \
  251.              STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL)         \
  252.                 (head)->stqh_last = &STAILQ_FIRST((head));              \
  253. } while (0)
  254.  
  255. #define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do {                 \
  256.         if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
  257.                 (head)->stqh_last = &STAILQ_FIRST((head));              \
  258. } while (0)
  259.  
  260. /*
  261.  * List declarations.
  262.  */
  263. #define LIST_HEAD(name, type)                                           \
  264. struct name {                                                           \
  265.         struct type *lh_first;  /* first element */                     \
  266. }
  267.  
  268. #define LIST_HEAD_INITIALIZER(head)                                     \
  269.         { NULL }
  270.  
  271. #define LIST_ENTRY(type)                                                \
  272. struct {                                                                \
  273.         struct type *le_next;   /* next element */                      \
  274.         struct type **le_prev;  /* address of previous next element */  \
  275. }
  276.  
  277. /*
  278.  * List functions.
  279.  */
  280.  
  281. #define LIST_EMPTY(head)        ((head)->lh_first == NULL)
  282.  
  283. #define LIST_FIRST(head)        ((head)->lh_first)
  284.  
  285. #define LIST_FOREACH(var, head, field)                                  \
  286.         for ((var) = LIST_FIRST((head));                                \
  287.             (var);                                                      \
  288.             (var) = LIST_NEXT((var), field))
  289.  
  290. #define LIST_INIT(head) do {                                            \
  291.         LIST_FIRST((head)) = NULL;                                      \
  292. } while (0)
  293.  
  294. #define LIST_INSERT_AFTER(listelm, elm, field) do {                     \
  295.         if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
  296.                 LIST_NEXT((listelm), field)->field.le_prev =            \
  297.                     &LIST_NEXT((elm), field);                           \
  298.         LIST_NEXT((listelm), field) = (elm);                            \
  299.         (elm)->field.le_prev = &LIST_NEXT((listelm), field);            \
  300. } while (0)
  301.  
  302. #define LIST_INSERT_BEFORE(listelm, elm, field) do {                    \
  303.         (elm)->field.le_prev = (listelm)->field.le_prev;                \
  304.         LIST_NEXT((elm), field) = (listelm);                            \
  305.         *(listelm)->field.le_prev = (elm);                              \
  306.         (listelm)->field.le_prev = &LIST_NEXT((elm), field);            \
  307. } while (0)
  308.  
  309. #define LIST_INSERT_HEAD(head, elm, field) do {                         \
  310.         if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)     \
  311.                 LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
  312.         LIST_FIRST((head)) = (elm);                                     \
  313.         (elm)->field.le_prev = &LIST_FIRST((head));                     \
  314. } while (0)
  315.  
  316. #define LIST_NEXT(elm, field)   ((elm)->field.le_next)
  317.  
  318. #define LIST_REMOVE(elm, field) do {                                    \
  319.         if (LIST_NEXT((elm), field) != NULL)                            \
  320.                 LIST_NEXT((elm), field)->field.le_prev =                \
  321.                     (elm)->field.le_prev;                               \
  322.         *(elm)->field.le_prev = LIST_NEXT((elm), field);                \
  323. } while (0)
  324.  
  325. /*
  326.  * Tail queue declarations.
  327.  */
  328. #define TAILQ_HEAD(name, type)                                          \
  329. struct name {                                                           \
  330.         struct type *tqh_first; /* first element */                     \
  331.         struct type **tqh_last; /* addr of last next element */         \
  332. }
  333.  
  334. #define TAILQ_HEAD_INITIALIZER(head)                                    \
  335.         { NULL, &(head).tqh_first }
  336.  
  337. #define TAILQ_ENTRY(type)                                               \
  338. struct {                                                                \
  339.         struct type *tqe_next;  /* next element */                      \
  340.         struct type **tqe_prev; /* address of previous next element */  \
  341. }
  342.  
  343. /*
  344.  * Tail queue functions.
  345.  */
  346. #define TAILQ_CONCAT(head1, head2, field) do {                          \
  347.         if (!TAILQ_EMPTY(head2)) {                                      \
  348.                 *(head1)->tqh_last = (head2)->tqh_first;                \
  349.                 (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
  350.                 (head1)->tqh_last = (head2)->tqh_last;                  \
  351.                 TAILQ_INIT((head2));                                    \
  352.         }                                                               \
  353. } while (0)
  354.  
  355. #define TAILQ_EMPTY(head)       ((head)->tqh_first == NULL)
  356.  
  357. #define TAILQ_FIRST(head)       ((head)->tqh_first)
  358.  
  359. #define TAILQ_FOREACH(var, head, field)                                 \
  360.         for ((var) = TAILQ_FIRST((head));                               \
  361.             (var);                                                      \
  362.             (var) = TAILQ_NEXT((var), field))
  363.  
  364. #define TAILQ_FOREACH_REVERSE(var, head, headname, field)               \
  365.         for ((var) = TAILQ_LAST((head), headname);                      \
  366.             (var);                                                      \
  367.             (var) = TAILQ_PREV((var), headname, field))
  368.  
  369. #define TAILQ_INIT(head) do {                                           \
  370.         TAILQ_FIRST((head)) = NULL;                                     \
  371.         (head)->tqh_last = &TAILQ_FIRST((head));                        \
  372. } while (0)
  373.  
  374. #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do {              \
  375.         if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
  376.                 TAILQ_NEXT((elm), field)->field.tqe_prev =              \
  377.                     &TAILQ_NEXT((elm), field);                          \
  378.         else                                                            \
  379.                 (head)->tqh_last = &TAILQ_NEXT((elm), field);           \
  380.         TAILQ_NEXT((listelm), field) = (elm);                           \
  381.         (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field);          \
  382. } while (0)
  383.  
  384. #define TAILQ_INSERT_BEFORE(listelm, elm, field) do {                   \
  385.         (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \
  386.         TAILQ_NEXT((elm), field) = (listelm);                           \
  387.         *(listelm)->field.tqe_prev = (elm);                             \
  388.         (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field);          \
  389. } while (0)
  390.  
  391. #define TAILQ_INSERT_HEAD(head, elm, field) do {                        \
  392.         if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL)   \
  393.                 TAILQ_FIRST((head))->field.tqe_prev =                   \
  394.                     &TAILQ_NEXT((elm), field);                          \
  395.         else                                                            \
  396.                 (head)->tqh_last = &TAILQ_NEXT((elm), field);           \
  397.         TAILQ_FIRST((head)) = (elm);                                    \
  398.         (elm)->field.tqe_prev = &TAILQ_FIRST((head));                   \
  399. } while (0)
  400.  
  401. #define TAILQ_INSERT_TAIL(head, elm, field) do {                        \
  402.         TAILQ_NEXT((elm), field) = NULL;                                \
  403.         (elm)->field.tqe_prev = (head)->tqh_last;                       \
  404.         *(head)->tqh_last = (elm);                                      \
  405.         (head)->tqh_last = &TAILQ_NEXT((elm), field);                   \
  406. } while (0)
  407.  
  408. #define TAILQ_LAST(head, headname)                                      \
  409.         (*(((struct headname *)((head)->tqh_last))->tqh_last))
  410.  
  411. #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
  412.  
  413. #define TAILQ_PREV(elm, headname, field)                                \
  414.         (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
  415.  
  416. #define TAILQ_REMOVE(head, elm, field) do {                             \
  417.         if ((TAILQ_NEXT((elm), field)) != NULL)                         \
  418.                 TAILQ_NEXT((elm), field)->field.tqe_prev =              \
  419.                     (elm)->field.tqe_prev;                              \
  420.         else                                                            \
  421.                 (head)->tqh_last = (elm)->field.tqe_prev;               \
  422.         *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field);              \
  423. } while (0)
  424.  
  425.  
  426. #ifdef _KERNEL
  427.  
  428. /*
  429.  * XXX insque() and remque() are an old way of handling certain queues.
  430.  * They bogusly assumes that all queue heads look alike.
  431.  */
  432.  
  433. struct quehead {
  434.         struct quehead *qh_link;
  435.         struct quehead *qh_rlink;
  436. };
  437.  
  438. #ifdef  __GNUC__
  439.  
  440. static __inline void
  441. insque(void *a, void *b)
  442. {
  443.         struct quehead *element = (struct quehead *)a,
  444.                  *head = (struct quehead *)b;
  445.  
  446.         element->qh_link = head->qh_link;
  447.         element->qh_rlink = head;
  448.         head->qh_link = element;
  449.         element->qh_link->qh_rlink = element;
  450. }
  451.  
  452. static __inline void
  453. remque(void *a)
  454. {
  455.         struct quehead *element = (struct quehead *)a;
  456.  
  457.         element->qh_link->qh_rlink = element->qh_rlink;
  458.         element->qh_rlink->qh_link = element->qh_link;
  459.         element->qh_rlink = 0;
  460. }
  461.  
  462. #else /* !__GNUC__ */
  463.  
  464. void    insque(void *a, void *b);
  465. void    remque(void *a);
  466.  
  467. #endif /* __GNUC__ */
  468.  
  469. #endif /* _KERNEL */
  470.  
  471. #endif /* !_SYS_QUEUE_H_ */
  472.