1 /* SPDX-License-Identifier: LGPL-2.1 */
2 /*
3 * Copyright (C) 2009 Red Hat Inc, Steven Rostedt <[email protected]>
4 *
5 */
6 #ifndef __LIST_H
7 #define __LIST_H
8
9 #define offset_of(type, field) __builtin_offsetof(type, field)
10 #define container_of(p, type, field) (type *)((long)p - offset_of(type, field))
11
12 struct list_head {
13 struct list_head *next;
14 struct list_head *prev;
15 };
16
list_head_init(struct list_head * list)17 static inline void list_head_init(struct list_head *list)
18 {
19 list->next = list;
20 list->prev = list;
21 }
22
list_add(struct list_head * p,struct list_head * head)23 static inline void list_add(struct list_head *p, struct list_head *head)
24 {
25 struct list_head *next = head->next;
26
27 p->prev = head;
28 p->next = next;
29 next->prev = p;
30 head->next = p;
31 }
32
list_add_tail(struct list_head * p,struct list_head * head)33 static inline void list_add_tail(struct list_head *p, struct list_head *head)
34 {
35 struct list_head *prev = head->prev;
36
37 p->prev = prev;
38 p->next = head;
39 prev->next = p;
40 head->prev = p;
41 }
42
list_del(struct list_head * p)43 static inline void list_del(struct list_head *p)
44 {
45 struct list_head *next = p->next;
46 struct list_head *prev = p->prev;
47
48 next->prev = prev;
49 prev->next = next;
50 }
51
list_empty(struct list_head * list)52 static inline int list_empty(struct list_head *list)
53 {
54 return list->next == list;
55 }
56
57 #define list_for_each_entry(p, list, field) \
58 for (p = container_of((list)->next, typeof(*p), field); \
59 &(p)->field != list; \
60 p = container_of((p)->field.next, typeof(*p), field))
61
62 #define list_for_each_entry_safe(p, n, list, field) \
63 for (p = container_of((list)->next, typeof(*p), field), \
64 n = container_of((p)->field.next, typeof(*p), field); \
65 &(p)->field != list; \
66 p = n, n = container_of((p)->field.next, typeof(*p), field))
67
68 #endif /* __LIST_H */
69