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