101e04c3fSmrg/**************************************************************************
201e04c3fSmrg *
301e04c3fSmrg * Copyright 2006 VMware, Inc., Bismarck, ND. USA.
401e04c3fSmrg * All Rights Reserved.
501e04c3fSmrg *
601e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
701e04c3fSmrg * copy of this software and associated documentation files (the
801e04c3fSmrg * "Software"), to deal in the Software without restriction, including
901e04c3fSmrg * without limitation the rights to use, copy, modify, merge, publish,
1001e04c3fSmrg * distribute, sub license, and/or sell copies of the Software, and to
1101e04c3fSmrg * permit persons to whom the Software is furnished to do so, subject to
1201e04c3fSmrg * the following conditions:
1301e04c3fSmrg *
1401e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1501e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1601e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
1701e04c3fSmrg * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
1801e04c3fSmrg * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
1901e04c3fSmrg * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2001e04c3fSmrg * USE OR OTHER DEALINGS IN THE SOFTWARE.
2101e04c3fSmrg *
2201e04c3fSmrg * The above copyright notice and this permission notice (including the
2301e04c3fSmrg * next paragraph) shall be included in all copies or substantial portions
2401e04c3fSmrg * of the Software.
2501e04c3fSmrg *
2601e04c3fSmrg **************************************************************************/
2701e04c3fSmrg
2801e04c3fSmrg/**
2901e04c3fSmrg * \file
3001e04c3fSmrg * List macros heavily inspired by the Linux kernel
3101e04c3fSmrg * list handling. No list looping yet.
3201e04c3fSmrg *
3301e04c3fSmrg * Is not threadsafe, so common operations need to
3401e04c3fSmrg * be protected using an external mutex.
3501e04c3fSmrg */
3601e04c3fSmrg
3701e04c3fSmrg#ifndef _UTIL_LIST_H_
3801e04c3fSmrg#define _UTIL_LIST_H_
3901e04c3fSmrg
4001e04c3fSmrg
4101e04c3fSmrg#include <stdbool.h>
4201e04c3fSmrg#include <stddef.h>
4301e04c3fSmrg#include <assert.h>
4401e04c3fSmrg#include "c99_compat.h"
4501e04c3fSmrg
467ec681f3Smrg#ifdef DEBUG
477ec681f3Smrg#  define list_assert(cond, msg)  assert(cond && msg)
487ec681f3Smrg#else
497ec681f3Smrg#  define list_assert(cond, msg)  (void)(0 && (cond))
507ec681f3Smrg#endif
5101e04c3fSmrg
5201e04c3fSmrgstruct list_head
5301e04c3fSmrg{
5401e04c3fSmrg    struct list_head *prev;
5501e04c3fSmrg    struct list_head *next;
5601e04c3fSmrg};
5701e04c3fSmrg
5801e04c3fSmrgstatic inline void list_inithead(struct list_head *item)
5901e04c3fSmrg{
6001e04c3fSmrg    item->prev = item;
6101e04c3fSmrg    item->next = item;
6201e04c3fSmrg}
6301e04c3fSmrg
6401e04c3fSmrgstatic inline void list_add(struct list_head *item, struct list_head *list)
6501e04c3fSmrg{
6601e04c3fSmrg    item->prev = list;
6701e04c3fSmrg    item->next = list->next;
6801e04c3fSmrg    list->next->prev = item;
6901e04c3fSmrg    list->next = item;
7001e04c3fSmrg}
7101e04c3fSmrg
7201e04c3fSmrgstatic inline void list_addtail(struct list_head *item, struct list_head *list)
7301e04c3fSmrg{
7401e04c3fSmrg    item->next = list;
7501e04c3fSmrg    item->prev = list->prev;
7601e04c3fSmrg    list->prev->next = item;
7701e04c3fSmrg    list->prev = item;
7801e04c3fSmrg}
7901e04c3fSmrg
807ec681f3Smrgstatic inline bool list_is_empty(const struct list_head *list);
8101e04c3fSmrg
8201e04c3fSmrgstatic inline void list_replace(struct list_head *from, struct list_head *to)
8301e04c3fSmrg{
847ec681f3Smrg    if (list_is_empty(from)) {
8501e04c3fSmrg        list_inithead(to);
8601e04c3fSmrg    } else {
8701e04c3fSmrg        to->prev = from->prev;
8801e04c3fSmrg        to->next = from->next;
8901e04c3fSmrg        from->next->prev = to;
9001e04c3fSmrg        from->prev->next = to;
9101e04c3fSmrg    }
9201e04c3fSmrg}
9301e04c3fSmrg
9401e04c3fSmrgstatic inline void list_del(struct list_head *item)
9501e04c3fSmrg{
9601e04c3fSmrg    item->prev->next = item->next;
9701e04c3fSmrg    item->next->prev = item->prev;
9801e04c3fSmrg    item->prev = item->next = NULL;
9901e04c3fSmrg}
10001e04c3fSmrg
10101e04c3fSmrgstatic inline void list_delinit(struct list_head *item)
10201e04c3fSmrg{
10301e04c3fSmrg    item->prev->next = item->next;
10401e04c3fSmrg    item->next->prev = item->prev;
10501e04c3fSmrg    item->next = item;
10601e04c3fSmrg    item->prev = item;
10701e04c3fSmrg}
10801e04c3fSmrg
1097ec681f3Smrgstatic inline bool list_is_empty(const struct list_head *list)
11001e04c3fSmrg{
11101e04c3fSmrg   return list->next == list;
11201e04c3fSmrg}
11301e04c3fSmrg
1147ec681f3Smrgstatic inline bool list_is_linked(const struct list_head *list)
1157ec681f3Smrg{
1167ec681f3Smrg   /* both must be NULL or both must be not NULL */
1177ec681f3Smrg   assert((list->prev != NULL) == (list->next != NULL));
1187ec681f3Smrg
1197ec681f3Smrg   return list->next != NULL;
1207ec681f3Smrg}
1217ec681f3Smrg
12201e04c3fSmrg/**
12301e04c3fSmrg * Returns whether the list has exactly one element.
12401e04c3fSmrg */
12501e04c3fSmrgstatic inline bool list_is_singular(const struct list_head *list)
12601e04c3fSmrg{
1277ec681f3Smrg   return list_is_linked(list) && !list_is_empty(list) && list->next->next == list;
12801e04c3fSmrg}
12901e04c3fSmrg
13001e04c3fSmrgstatic inline unsigned list_length(const struct list_head *list)
13101e04c3fSmrg{
13201e04c3fSmrg   struct list_head *node;
13301e04c3fSmrg   unsigned length = 0;
13401e04c3fSmrg   for (node = list->next; node != list; node = node->next)
13501e04c3fSmrg      length++;
13601e04c3fSmrg   return length;
13701e04c3fSmrg}
13801e04c3fSmrg
13901e04c3fSmrgstatic inline void list_splice(struct list_head *src, struct list_head *dst)
14001e04c3fSmrg{
1417ec681f3Smrg   if (list_is_empty(src))
14201e04c3fSmrg      return;
14301e04c3fSmrg
14401e04c3fSmrg   src->next->prev = dst;
14501e04c3fSmrg   src->prev->next = dst->next;
14601e04c3fSmrg   dst->next->prev = src->prev;
14701e04c3fSmrg   dst->next = src->next;
14801e04c3fSmrg}
14901e04c3fSmrg
15001e04c3fSmrgstatic inline void list_splicetail(struct list_head *src, struct list_head *dst)
15101e04c3fSmrg{
1527ec681f3Smrg   if (list_is_empty(src))
15301e04c3fSmrg      return;
15401e04c3fSmrg
15501e04c3fSmrg   src->prev->next = dst;
15601e04c3fSmrg   src->next->prev = dst->prev;
15701e04c3fSmrg   dst->prev->next = src->next;
15801e04c3fSmrg   dst->prev = src->prev;
15901e04c3fSmrg}
16001e04c3fSmrg
16101e04c3fSmrgstatic inline void list_validate(const struct list_head *list)
16201e04c3fSmrg{
16301e04c3fSmrg   struct list_head *node;
1647ec681f3Smrg   assert(list_is_linked(list));
16501e04c3fSmrg   assert(list->next->prev == list && list->prev->next == list);
16601e04c3fSmrg   for (node = list->next; node != list; node = node->next)
16701e04c3fSmrg      assert(node->next->prev == node && node->prev->next == node);
16801e04c3fSmrg}
16901e04c3fSmrg
17001e04c3fSmrg#define LIST_ENTRY(__type, __item, __field)   \
17101e04c3fSmrg    ((__type *)(((char *)(__item)) - offsetof(__type, __field)))
17201e04c3fSmrg
17301e04c3fSmrg/**
17401e04c3fSmrg * Cast from a pointer to a member of a struct back to the containing struct.
17501e04c3fSmrg *
17601e04c3fSmrg * 'sample' MUST be initialized, or else the result is undefined!
17701e04c3fSmrg */
1787ec681f3Smrg#define list_container_of(ptr, sample, member)				\
17901e04c3fSmrg    (void *)((char *)(ptr)						\
18001e04c3fSmrg	     - ((char *)&(sample)->member - (char *)(sample)))
18101e04c3fSmrg
18201e04c3fSmrg#define list_first_entry(ptr, type, member) \
18301e04c3fSmrg        LIST_ENTRY(type, (ptr)->next, member)
18401e04c3fSmrg
18501e04c3fSmrg#define list_last_entry(ptr, type, member) \
18601e04c3fSmrg        LIST_ENTRY(type, (ptr)->prev, member)
18701e04c3fSmrg
18801e04c3fSmrg
18901e04c3fSmrg#define LIST_FOR_EACH_ENTRY(pos, head, member)				\
1907ec681f3Smrg   for (pos = NULL, pos = list_container_of((head)->next, pos, member);	\
19101e04c3fSmrg	&pos->member != (head);						\
1927ec681f3Smrg	pos = list_container_of(pos->member.next, pos, member))
19301e04c3fSmrg
19401e04c3fSmrg#define LIST_FOR_EACH_ENTRY_SAFE(pos, storage, head, member)	\
1957ec681f3Smrg   for (pos = NULL, pos = list_container_of((head)->next, pos, member),	\
1967ec681f3Smrg	storage = list_container_of(pos->member.next, pos, member);	\
19701e04c3fSmrg	&pos->member != (head);						\
1987ec681f3Smrg	pos = storage, storage = list_container_of(storage->member.next, storage, member))
19901e04c3fSmrg
20001e04c3fSmrg#define LIST_FOR_EACH_ENTRY_SAFE_REV(pos, storage, head, member)	\
2017ec681f3Smrg   for (pos = NULL, pos = list_container_of((head)->prev, pos, member),	\
2027ec681f3Smrg	storage = list_container_of(pos->member.prev, pos, member);		\
20301e04c3fSmrg	&pos->member != (head);						\
2047ec681f3Smrg	pos = storage, storage = list_container_of(storage->member.prev, storage, member))
20501e04c3fSmrg
20601e04c3fSmrg#define LIST_FOR_EACH_ENTRY_FROM(pos, start, head, member)		\
2077ec681f3Smrg   for (pos = NULL, pos = list_container_of((start), pos, member);		\
20801e04c3fSmrg	&pos->member != (head);						\
2097ec681f3Smrg	pos = list_container_of(pos->member.next, pos, member))
21001e04c3fSmrg
21101e04c3fSmrg#define LIST_FOR_EACH_ENTRY_FROM_REV(pos, start, head, member)		\
2127ec681f3Smrg   for (pos = NULL, pos = list_container_of((start), pos, member);		\
21301e04c3fSmrg	&pos->member != (head);						\
2147ec681f3Smrg	pos = list_container_of(pos->member.prev, pos, member))
21501e04c3fSmrg
21601e04c3fSmrg#define list_for_each_entry(type, pos, head, member)                    \
2177ec681f3Smrg   for (type *pos = LIST_ENTRY(type, (head)->next, member),             \
2187ec681f3Smrg	     *__next = LIST_ENTRY(type, pos->member.next, member);      \
21901e04c3fSmrg	&pos->member != (head);                                         \
2207ec681f3Smrg	pos = LIST_ENTRY(type, pos->member.next, member),               \
2217ec681f3Smrg	list_assert(pos == __next, "use _safe iterator"),               \
2227ec681f3Smrg	__next = LIST_ENTRY(type, __next->member.next, member))
22301e04c3fSmrg
22401e04c3fSmrg#define list_for_each_entry_safe(type, pos, head, member)               \
22501e04c3fSmrg   for (type *pos = LIST_ENTRY(type, (head)->next, member),             \
22601e04c3fSmrg	     *__next = LIST_ENTRY(type, pos->member.next, member);      \
22701e04c3fSmrg	&pos->member != (head);                                         \
22801e04c3fSmrg	pos = __next,                                                   \
2297ec681f3Smrg	__next = LIST_ENTRY(type, __next->member.next, member))
23001e04c3fSmrg
23101e04c3fSmrg#define list_for_each_entry_rev(type, pos, head, member)                \
2327ec681f3Smrg   for (type *pos = LIST_ENTRY(type, (head)->prev, member),             \
2337ec681f3Smrg	     *__prev = LIST_ENTRY(type, pos->member.prev, member);      \
23401e04c3fSmrg	&pos->member != (head);                                         \
2357ec681f3Smrg	pos = LIST_ENTRY(type, pos->member.prev, member),               \
2367ec681f3Smrg	list_assert(pos == __prev, "use _safe iterator"),               \
2377ec681f3Smrg	__prev = LIST_ENTRY(type, __prev->member.prev, member))
23801e04c3fSmrg
23901e04c3fSmrg#define list_for_each_entry_safe_rev(type, pos, head, member)           \
24001e04c3fSmrg   for (type *pos = LIST_ENTRY(type, (head)->prev, member),             \
24101e04c3fSmrg	     *__prev = LIST_ENTRY(type, pos->member.prev, member);      \
24201e04c3fSmrg	&pos->member != (head);                                         \
24301e04c3fSmrg	pos = __prev,                                                   \
24401e04c3fSmrg        __prev = LIST_ENTRY(type, __prev->member.prev, member))
24501e04c3fSmrg
24601e04c3fSmrg#define list_for_each_entry_from(type, pos, start, head, member)        \
24701e04c3fSmrg   for (type *pos = LIST_ENTRY(type, (start), member);                  \
24801e04c3fSmrg	&pos->member != (head);                                         \
24901e04c3fSmrg	pos = LIST_ENTRY(type, pos->member.next, member))
25001e04c3fSmrg
2517ec681f3Smrg#define list_for_each_entry_from_safe(type, pos, start, head, member)   \
2527ec681f3Smrg   for (type *pos = LIST_ENTRY(type, (start), member),                  \
2537ec681f3Smrg	     *__next = LIST_ENTRY(type, pos->member.next, member);      \
2547ec681f3Smrg	&pos->member != (head);                                         \
2557ec681f3Smrg	pos = __next,                                                   \
2567ec681f3Smrg	__next = LIST_ENTRY(type, __next->member.next, member))
2577ec681f3Smrg
25801e04c3fSmrg#define list_for_each_entry_from_rev(type, pos, start, head, member)    \
25901e04c3fSmrg   for (type *pos = LIST_ENTRY(type, (start), member);                  \
26001e04c3fSmrg	&pos->member != (head);                                         \
26101e04c3fSmrg	pos = LIST_ENTRY(type, pos->member.prev, member))
26201e04c3fSmrg
2637ec681f3Smrg#define list_pair_for_each_entry(type, pos1, pos2, head1, head2, member) \
2647ec681f3Smrg   for (type *pos1 = LIST_ENTRY(type, (head1)->next, member),           \
2657ec681f3Smrg             *pos2 = LIST_ENTRY(type, (head2)->next, member);           \
2667ec681f3Smrg        &pos1->member != (head1) && &pos2->member != (head2);           \
2677ec681f3Smrg	pos1 = LIST_ENTRY(type, pos1->member.next, member),               \
2687ec681f3Smrg	pos2 = LIST_ENTRY(type, pos2->member.next, member))
2697ec681f3Smrg
27001e04c3fSmrg#endif /*_UTIL_LIST_H_*/
271