/* * Copyright (C) 2002 Free Software Foundation, Inc. * (originally part of the GNU C Library and Userspace RCU) * Contributed by Ulrich Drepper , 2002. * * Copyright (C) 2009 Pierre-Marc Fournier * Conversion to RCU list. * Copyright (C) 2010 Mathieu Desnoyers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see * . */ #ifndef LIST_H #define LIST_H #include /* * The definitions of this file are adopted from those which can be * found in the Linux kernel headers to enable people familiar with the * latter find their way in these sources as well. */ /* Basic type for the double-link list. */ struct list_head { struct list_head *next, *prev; }; /* avoid conflicts with BSD-only sys/queue.h */ #undef LIST_HEAD /* Define a variable with the head and tail of the list. */ #define LIST_HEAD(name) struct list_head name = { &(name), &(name) } /* Initialize a new list head. */ #define INIT_LIST_HEAD(ptr) (ptr)->next = (ptr)->prev = (ptr) #define LIST_HEAD_INIT(name) \ { \ .next = &(name), .prev = &(name), \ } /* Add new element at the head of the list. */ static inline void list_add(struct list_head *newp, struct list_head *head) { head->next->prev = newp; newp->next = head->next; newp->prev = head; head->next = newp; } /* Add new element at the tail of the list. */ static inline void list_add_tail(struct list_head *newp, struct list_head *head) { head->prev->next = newp; newp->next = head; newp->prev = head->prev; head->prev = newp; } /* Remove element from list. */ static inline void __list_del(struct list_head *prev, struct list_head *next) { next->prev = prev; prev->next = next; } /* Remove element from list. */ static inline void list_del(struct list_head *elem) { __list_del(elem->prev, elem->next); } /* Remove element from list, initializing the element's list pointers. */ static inline void list_del_init(struct list_head *elem) { list_del(elem); INIT_LIST_HEAD(elem); } /* Delete from list, add to another list as head. */ static inline void list_move(struct list_head *elem, struct list_head *head) { __list_del(elem->prev, elem->next); list_add(elem, head); } /* Replace an old entry. */ static inline void list_replace(struct list_head *old, struct list_head *newp) { newp->next = old->next; newp->prev = old->prev; newp->prev->next = newp; newp->next->prev = newp; } /* Join two lists. */ static inline void list_splice(struct list_head *add, struct list_head *head) { /* Do nothing if the list which gets added is empty. */ if (add != add->next) { add->next->prev = head; add->prev->next = head->next; head->next->prev = add->prev; head->next = add->next; } } /** * list_is_head - tests whether @list is the list @head * @list: the entry to test * @head: the head of the list */ static inline int list_is_head(const struct list_head *list, const struct list_head *head) { return list == head; } /** * list_empty - tests whether a list is empty * @head: the list to test. */ static inline int list_empty(struct list_head *head) { return head == head->next; } static inline void list_replace_init(struct list_head *old, struct list_head *newp) { struct list_head *head = old->next; list_del(old); list_add_tail(newp, head); INIT_LIST_HEAD(old); } /** * list_entry - get the struct for this entry * @ptr: the &struct list_head pointer. * @type: the type of the struct this is embedded in. * @member: the name of the list_head within the struct. */ #define list_entry(ptr, type, member) \ ((type *)((char *)(ptr)-offsetof(type, member))) /** * list_first_entry - get the first element from a list * @ptr: the list head to take the element from. * @type: the type of the struct this is embedded in. * @member: the name of the list_head within the struct. * * Note, that list is expected to be not empty. */ #define list_first_entry(ptr, type, member) \ list_entry((ptr)->next, type, member) /** * list_last_entry - get the last element from a list * @ptr: the list head to take the element from. * @type: the type of the struct this is embedded in. * @member: the name of the list_head within the struct. * * Note, that list is expected to be not empty. */ #define list_last_entry(ptr, type, member) list_entry((ptr)->prev, type, member) /** * list_next_entry - get the next element in list * @pos: the type * to cursor * @member: the name of the list_head within the struct. */ #define list_next_entry(pos, member) \ list_entry((pos)->member.next, typeof(*(pos)), member) /** * __typed_list_for_each() - macro for making other typed for_each macros. * @Te: list entry type. * @e: entry. * @emember: member of the entry structure that holds list_head. * @l: list head to iterate over. * @lmember: member of the list head structure that holds list_head. */ #define __typed_list_for_each(Te, e, emember, l, lmember) \ for (e = list_first_entry(&(l)->lmember, Te, emember); \ &e->emember != &(l)->lmember; \ e = list_entry(e->emember.next, Te, emember)) /** * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. */ #define list_for_each(pos, head) \ for (pos = (head)->next; !list_is_head(pos, (head)); pos = pos->next) /** * list_for_each_prev - iterate over a list backwards * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. */ #define list_for_each_prev(pos, head) \ for (pos = (head)->prev; !list_is_head(pos, (head)); pos = pos->prev) /** * list_for_each_safe - iterate over a list safe against removal of list entry * @pos: the &struct list_head to use as a loop cursor. * @n: another &struct list_head to use as temporary storage * @head: the head for your list. */ #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; !list_is_head(pos, (head)); \ pos = n, n = pos->next) /** * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry * @pos: the &struct list_head to use as a loop cursor. * @n: another &struct list_head to use as temporary storage * @head: the head for your list. */ #define list_for_each_prev_safe(pos, n, head) \ for (pos = (head)->prev, n = pos->prev; !list_is_head(pos, (head)); \ pos = n, n = pos->prev) /** * list_entry_is_head - test if the entry points to the head of the list * @pos: the type * to cursor * @head: the head for your list. * @member: the name of the list_head within the struct. */ #define list_entry_is_head(pos, head, member) (&pos->member == (head)) /** * list_for_each_entry - iterate over list of given type * @pos: the type * to use as a loop cursor. * @head: the head for your list. * @member: the name of the list_head within the struct. */ #define list_for_each_entry(pos, head, member) \ for (pos = list_first_entry(head, typeof(*pos), member); \ !list_entry_is_head(pos, head, member); \ pos = list_next_entry(pos, member)) /** * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry * @pos: the type * to use as a loop cursor. * @n: another type * to use as temporary storage * @head: the head for your list. * @member: the name of the list_head within the struct. */ #define list_for_each_entry_safe(pos, n, head, member) \ for (pos = list_first_entry(head, typeof(*pos), member), \ n = list_next_entry(pos, member); \ !list_entry_is_head(pos, head, member); \ pos = n, n = list_next_entry(n, member)) /* * This is exactly the same as a normal list_head, except that it can be * declared volatile (e.g., if you have a list that may be accessed from signal * handlers). */ struct volatile_list_head { volatile struct volatile_list_head *next, *prev; }; #define VOLATILE_LIST_HEAD(name) \ volatile struct volatile_list_head name = { &(name), &(name) } static inline void __volatile_list_del(volatile struct volatile_list_head *prev, volatile struct volatile_list_head *next) { next->prev = prev; prev->next = next; } static inline void volatile_list_del(volatile struct volatile_list_head *elem) { __volatile_list_del(elem->prev, elem->next); } static inline int volatile_list_empty(volatile struct volatile_list_head *head) { return head == head->next; } static inline void volatile_list_add(volatile struct volatile_list_head *newp, volatile struct volatile_list_head *head) { head->next->prev = newp; newp->next = head->next; newp->prev = head; head->next = newp; } #endif /* LIST_H */