| /* Doubly linked list macros compatible with Linux kernel's version | |
| * Copyright (c) 2015 by Takashi Iwai <tiwai@suse.de> | |
| * | |
| * 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 program 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. | |
| */ | |
| #ifndef _LIST_H | |
| #define _LIST_H | |
| #include <stddef.h> | |
| struct list_head { | |
| struct list_head *next; | |
| struct list_head *prev; | |
| }; | |
| /* one-shot definition of a list head */ | |
| #define LIST_HEAD(x) \ | |
| struct list_head x = { &x, &x } | |
| /* initialize a list head explicitly */ | |
| static inline void INIT_LIST_HEAD(struct list_head *p) | |
| { | |
| p->next = p->prev = p; | |
| } | |
| #define list_entry_offset(p, type, offset) \ | |
| ((type *)((char *)(p) - (offset))) | |
| /* list_entry - retrieve the original struct from list_head | |
| * @p: list_head pointer | |
| * @type: struct type | |
| * @member: struct field member containing the list_head | |
| */ | |
| #define list_entry(p, type, member) \ | |
| list_entry_offset(p, type, offsetof(type, member)) | |
| /* list_for_each - iterate over the linked list | |
| * @p: iterator, a list_head pointer variable | |
| * @list: list_head pointer containing the list | |
| */ | |
| #define list_for_each(p, list) \ | |
| for (p = (list)->next; p != (list); p = p->next) | |
| /* list_for_each_safe - iterate over the linked list, safe to delete | |
| * @p: iterator, a list_head pointer variable | |
| * @s: a temporary variable to keep the next, a list_head pointer, too | |
| * @list: list_head pointer containing the list | |
| */ | |
| #define list_for_each_safe(p, s, list) \ | |
| for (p = (list)->next; s = p->next, p != (list); p = s) | |
| /* list_add - prepend a list entry at the head | |
| * @p: the new list entry to add | |
| * @list: the list head | |
| */ | |
| static inline void list_add(struct list_head *p, struct list_head *list) | |
| { | |
| struct list_head *first = list->next; | |
| p->next = first; | |
| first->prev = p; | |
| list->next = p; | |
| p->prev = list; | |
| } | |
| /* list_add_tail - append a list entry at the tail | |
| * @p: the new list entry to add | |
| * @list: the list head | |
| */ | |
| static inline void list_add_tail(struct list_head *p, struct list_head *list) | |
| { | |
| struct list_head *last = list->prev; | |
| last->next = p; | |
| p->prev = last; | |
| p->next = list; | |
| list->prev = p; | |
| } | |
| /* list_insert - insert a new list entry between two known consecutive entries | |
| * @p: the new entry to be inserted between prev and next | |
| * @prev: the left-side entry | |
| * @next: the right-side entry | |
| */ | |
| static inline void list_insert(struct list_head *p, | |
| struct list_head *prev, | |
| struct list_head *next) | |
| { | |
| next->prev = p; | |
| p->next = next; | |
| p->prev = prev; | |
| prev->next = p; | |
| } | |
| /* list_del - delete the given list entry */ | |
| static inline void list_del(struct list_head *p) | |
| { | |
| p->prev->next = p->next; | |
| p->next->prev = p->prev; | |
| } | |
| /* list_empty - returns 1 if the given list is empty */ | |
| static inline int list_empty(const struct list_head *p) | |
| { | |
| return p->next == p; | |
| } | |
| #endif /* _LIST_H */ |