138 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2#ifndef _LIST_H3#define _LIST_H4 5/* Stripped down implementation of linked list taken6 * from the Linux Kernel.7 */8 9/*10 * Simple doubly linked list implementation.11 *12 * Some of the internal functions ("__xxx") are useful when13 * manipulating whole lists rather than single entries, as14 * sometimes we already know the next/prev entries and we can15 * generate better code by using them directly rather than16 * using the generic single-entry routines.17 */18 19struct list_head {20 struct list_head *next, *prev;21};22 23#define LIST_HEAD_INIT(name) { &(name), &(name) }24 25#define LIST_HEAD(name) \26 struct list_head name = LIST_HEAD_INIT(name)27 28static inline void INIT_LIST_HEAD(struct list_head *list)29{30 list->next = list;31 list->prev = list;32}33 34/*35 * Insert a new entry between two known consecutive entries.36 *37 * This is only for internal list manipulation where we know38 * the prev/next entries already!39 */40static inline void __list_add(struct list_head *new,41 struct list_head *prev,42 struct list_head *next)43{44 next->prev = new;45 new->next = next;46 new->prev = prev;47 prev->next = new;48}49 50/**51 * list_add - add a new entry52 * @new: new entry to be added53 * @head: list head to add it after54 *55 * Insert a new entry after the specified head.56 * This is good for implementing stacks.57 */58static inline void list_add(struct list_head *new, struct list_head *head)59{60 __list_add(new, head, head->next);61}62 63/*64 * Delete a list entry by making the prev/next entries65 * point to each other.66 *67 * This is only for internal list manipulation where we know68 * the prev/next entries already!69 */70static inline void __list_del(struct list_head * prev, struct list_head * next)71{72 next->prev = prev;73 prev->next = next;74}75 76#define POISON_POINTER_DELTA 077#define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA)78#define LIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA)79 80static inline void __list_del_entry(struct list_head *entry)81{82 __list_del(entry->prev, entry->next);83}84 85/**86 * list_del - deletes entry from list.87 * @entry: the element to delete from the list.88 * Note: list_empty() on entry does not return true after this, the entry is89 * in an undefined state.90 */91static inline void list_del(struct list_head *entry)92{93 __list_del(entry->prev, entry->next);94 entry->next = LIST_POISON1;95 entry->prev = LIST_POISON2;96}97 98/**99 * list_entry - get the struct for this entry100 * @ptr: the &struct list_head pointer.101 * @type: the type of the struct this is embedded in.102 * @member: the name of the list_head within the struct.103 */104#define list_entry(ptr, type, member) \105 container_of(ptr, type, member)106/**107 * list_for_each - iterate over a list108 * @pos: the &struct list_head to use as a loop cursor.109 * @head: the head for your list.110 */111#define list_for_each(pos, head) \112 for (pos = (head)->next; pos != (head); pos = pos->next)113 114/**115 * list_for_each_safe - iterate over a list safe against removal of list entry116 * @pos: the &struct list_head to use as a loop cursor.117 * @n: another &struct list_head to use as temporary storage118 * @head: the head for your list.119 */120#define list_for_each_safe(pos, n, head) \121 for (pos = (head)->next, n = pos->next; pos != (head); \122 pos = n, n = pos->next)123 124#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)125 126/**127 * container_of - cast a member of a structure out to the containing structure128 * @ptr: the pointer to the member.129 * @type: the type of the container struct this is embedded in.130 * @member: the name of the member within the struct.131 *132 */133#define container_of(ptr, type, member) ({ \134 const typeof( ((type *)0)->member ) *__mptr = (ptr); \135 (type *)( (char *)__mptr - offsetof(type,member) );})136 137#endif138