Annotation of embedaddon/bird2/lib/slists.h, revision 1.1

1.1     ! misho       1: /*
        !             2:  *     BIRD Library -- Safe Linked Lists
        !             3:  *
        !             4:  *     (c) 1998 Martin Mares <mj@ucw.cz>
        !             5:  *
        !             6:  *     Can be freely distributed and used under the terms of the GNU GPL.
        !             7:  */
        !             8: 
        !             9: #ifndef _BIRD_SLISTS_H_
        !            10: #define _BIRD_SLISTS_H_
        !            11: 
        !            12: /*
        !            13:  *  These linked lists work in a way similar to standard lists defined
        !            14:  *  in lib/lists.h, but in addition to all usual list functions they
        !            15:  *  provide fast deletion/insertion/everything-safe asynchronous
        !            16:  *  walking.
        !            17:  *
        !            18:  *  Example:
        !            19:  *             slist l;
        !            20:  *             siterator i;
        !            21:  *             snode *n;
        !            22:  *
        !            23:  *             s_init(&i, &l);         // Initialize iteration
        !            24:  *             ...
        !            25:  *             n = s_get(&i);          // Some time later, fetch present
        !            26:  *                                     // value of the iterator and unlink it
        !            27:  *                                     // from the list.
        !            28:  *             while (n->next) {
        !            29:  *                  ...
        !            30:  *                  if (decided_to_stop) {
        !            31:  *                     s_put(&i, n);   // Store current position (maybe even
        !            32:  *                                     // that we stay at list end)
        !            33:  *                     return;         // and return
        !            34:  *                  }
        !            35:  *                  ...
        !            36:  *             }
        !            37:  *             // After finishing, don't link the iterator back
        !            38:  */
        !            39: 
        !            40: typedef struct snode {
        !            41:   struct snode *next, *prev;
        !            42:   struct siterator *readers;
        !            43: } snode;
        !            44: 
        !            45: typedef struct slist {                 /* In fact two overlayed snodes */
        !            46:   struct snode *head, *null, *tail;
        !            47:   struct siterator *tail_readers;
        !            48: } slist;
        !            49: 
        !            50: typedef struct siterator {
        !            51:   /*
        !            52:    * Caution: Layout of this structure depends hard on layout of the
        !            53:    *         snode. Our `next' must be at position of snode `readers'
        !            54:    *         field, our `null' must be at position of `prev' and it must
        !            55:    *         contain NULL in order to distinguish between siterator
        !            56:    *         and snode (snodes with NULL `prev' field never carry
        !            57:    *         iterators). You are not expected to understand this.
        !            58:    */
        !            59:   struct siterator *prev, *null, *next;
        !            60:   /*
        !            61:    * For recently merged nodes this can be NULL, but then it's NULL
        !            62:    * for all successors as well. This is done to speed up iterator
        !            63:    * merging when there are lots of deletions.
        !            64:    */
        !            65:   snode *node;
        !            66: } siterator;
        !            67: 
        !            68: #define SNODE (snode *)
        !            69: #define SHEAD(list) ((void *)((list).head))
        !            70: #define STAIL(list) ((void *)((list).tail))
        !            71: #define SNODE_NEXT(n) ((void *)((SNODE (n))->next))
        !            72: #define SNODE_VALID(n) ((SNODE (n))->next)
        !            73: 
        !            74: #define WALK_SLIST(n,list) for(n=SHEAD(list); SNODE_VALID(n); n=SNODE_NEXT(n))
        !            75: #define WALK_SLIST_DELSAFE(n,nxt,list) \
        !            76:      for(n=SHEAD(list); nxt=SNODE_NEXT(n); n=(void *) nxt)
        !            77: #define EMPTY_SLIST(list) (!(list).head->next)
        !            78: 
        !            79: void s_add_tail(slist *, snode *);
        !            80: void s_add_head(slist *, snode *);
        !            81: void s_rem_node(snode *);
        !            82: void s_add_tail_list(slist *, slist *);
        !            83: void s_init_list(slist *);
        !            84: void s_insert_node(snode *, snode *);
        !            85: 
        !            86: snode *s_get(siterator *);
        !            87: void s_put(siterator *, snode *n);
        !            88: static inline void s_init(siterator *i, slist *l) { s_put(i, SHEAD(*l)); }
        !            89: static inline int s_is_used(siterator *i) { return (i->prev != NULL); }
        !            90: 
        !            91: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>