forked from sysprog21/phonebook-concurrent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
list.h
133 lines (107 loc) · 2.81 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
#include <stddef.h> // for offsefof
typedef struct __LIST_HEAD {
struct __LIST_HEAD *next, *prev;
} list_t;
/* Declr an empty list head */
#define LIST_HEAD_INIT(name) { &(name), &(name) }
inline
void INIT_LIST_HEAD(list_t *list)
__attribute__((always_inline));
inline
int list_empty(const list_t *head)
__attribute__((always_inline));
inline
void __list_add(list_t *new, list_t *prev, list_t *next)
__attribute__((always_inline));
inline
void list_add_tail(list_t *new, list_t *head)
__attribute__((always_inline));
inline
void list_add(list_t *new, list_t *head)
__attribute__((always_inline));
inline
void __list_splice(const list_t *list, list_t *prev, list_t *next)
__attribute__((always_inline));
inline
void list_splice(const list_t *list, list_t *head)
__attribute__((always_inline));
inline
void list_splice_tail(list_t *list, list_t *head)
__attribute__((always_inline));
inline
void INIT_LIST_HEAD(list_t *list)
{
list->next = list;
list->prev = list;
}
inline
int list_empty(const list_t *head)
{
return head->next == head;
}
inline
void __list_add(list_t *new, list_t *prev, list_t *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
/* Push to linked list's head (stack) */
inline
void list_add(list_t *new, list_t *head)
{
__list_add(new, head, head->next);
}
inline
void list_add_tail(list_t *new, list_t *head)
{
__list_add(new, head->prev, head);
}
inline
void __list_splice(const list_t *list, list_t *prev, list_t *next)
{
list_t *first = list->next;
list_t *last = list->prev;
first->prev = prev;
prev->next = first;
last->next = next;
next->prev = last;
}
/**
* list_splice - join two lists, this is designed for stacks
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
inline
void list_splice(const list_t *list, list_t *head)
{
if (!list_empty(list)) {
__list_splice(list, head, head->next);
}
}
/**
* list_splice_tail - join two lists, each list being a queue
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
inline
void list_splice_tail(list_t *list, list_t *head)
{
if (!list_empty(list)) {
__list_splice(list, head->prev, head);
}
}
/* get a pointer pointting to `type` */
#define list_entry(ptr, type, member) \
(type *)((char *)ptr - offsetof(type, member))
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
#define list_next_entry(pos, member) \
list_entry((pos)->member.next, typeof(*(pos)), member)
#define list_for_each_entry(pos, head, member) \
for (pos = list_first_entry(head, typeof(*pos), member); \
&pos->member != (head); \
pos = list_next_entry(pos, member))