-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlist.h
140 lines (120 loc) · 3.78 KB
/
list.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#ifndef _LIST_H_
#define _LIST_H_
/**
* A node in a doubly linked list.
* @next and @prev point to the next and previous node in the doubly linked list respectively.
*/
typedef struct list_head {
struct list_head *next, *prev;
} list_head_t;
typedef list_head_t list_t;
/**
* Initialize a list.
*/
static inline void INIT_LIST_HEAD(list_t *list)
{
list->next = list;
list->prev = list;
}
static inline void __list_add(list_head_t *_new,
list_head_t *prev,
list_head_t *next)
{
next->prev = _new;
_new->next = next;
_new->prev = prev;
prev->next = _new;
}
/**
* Append @_new to @head.
*/
static inline void list_append(list_head_t *_new, list_head_t *head)
{
__list_add(_new, head, head->next);
}
/**
* Prepend @_new to @head.
*/
static inline void list_prepend(list_head_t *_new, list_head_t *head)
{
__list_add(_new, head->prev, head);
}
/**
* Is the list empty?
*/
static inline int list_empty(const list_t *head)
{
return head->next == head;
}
static inline void __list_rm(list_head_t *prev, list_head_t *next)
{
next->prev = prev;
prev->next = next;
}
#define LIST_POISON1 ((void *) 0x00100100)
#define LIST_POISON2 ((void *) 0x00200200)
/**
* Remove @entry from the list.
*/
static inline void list_rm(list_head_t *entry)
{
__list_rm(entry->prev, entry->next);
entry->next = (list_head_t *)LIST_POISON1;
entry->prev = (list_head_t *)LIST_POISON2;
}
#define LIST_HEAD_INIT(name) {&(name), &(name)}
/**
* Macro version of INIT_LIST_HEAD.
*/
#define LIST_HEAD(name) \
list_head_t name = LIST_HEAD_INIT(name)
#undef offsetof
#define offsetof(type, member) ( (size_t) &( (type *)0 )->member )
/**
* Cast the variable who contains @ptr to @type.
* @ptr - a list_head_t variable
* @type - to what @type
* @member - the name of list_head_t variable defined in @type
*/
#define cast_to(ptr, type, member) \
((type *)((char *)(const list_t *)(ptr) - offsetof(type, member)))
/**
* Return the variable who contains @ptr as a @type variable.
* @ptr - a list_head_t variable
* @type - to what @type
* @member - the name of list_head_t variable defined in @type
*/
#define list_entry(ptr, type, member) \
cast_to(ptr, type, member)
/**
* Return the variable who contains @ptr->next as a @type variable.
* @ptr - a list_head_t variable
* @type - to what @type
* @member - the name of list_head_t variable defined in @type
*/
#define list_first_entry(ptr, type, member) \
list_entry( (ptr)->next, type, member )
/**
* Return the next entry of @pos.
* @pos - where I am in the doubly linked list.
* @member - the name of list_head_t variable defined in the type of @pos
*/
#define list_next_entry(pos, member, type) \
list_entry( (pos)->member.next, type, member )
/**
* Iterate over a list.
* @pos - @pos will be pointed to the address of next node.
* @head - where I am in the doubly linked list.
* @member - the name of list_head_t variable defined in the type of @pos
*/
#define list_iterate(pos, head, member, type) \
for(pos = list_first_entry(head, type, member); \
&pos->member != (head); \
pos = list_next_entry(pos, member, type))
/* Iterate over a list of given type safe against removal of list entry. */
#define list_iterate_safe(pos, n, head, member, type) \
for (pos = list_first_entry(head, type, member), \
n = list_next_entry(pos, member, type); \
&pos->member != (head); \
pos = n, n = list_next_entry(n, member, type))
#endif /* _LIST_H_ */