• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  #ifndef _LIST_H_
2  #define _LIST_H_
3  
4  #include <stddef.h>
5  
6  #ifndef offsetof
7  #define offsetof(type, md) ((size_t)&((type *)0)->md)
8  #endif
9  
10  #ifndef container_of
11  #define container_of(ptr, type, member) \
12    ((type *)((char *)(ptr) - offsetof(type, member)))
13  #endif
14  
15  struct list_item {
16  	struct list_item *next;
17  	struct list_item *prev;
18  };
19  
20  struct list {
21  	struct list_item *head;
22  	struct list_item *tail;
23  };
24  
25  #define LIST_INIT(name) { 0, 0 }
26  
27  #define LIST(name) \
28  	struct list name = LIST_INIT(name)
29  
30  #define list_entry(ptr, type, member) \
31  	container_of(ptr, type, member)
32  
list_init(struct list * list)33  static inline void list_init(struct list *list)
34  {
35  	list->head = 0;
36  	list->tail = 0;
37  }
38  
list_append(struct list * list,struct list_item * item)39  static inline void list_append(struct list *list, struct list_item *item)
40  {
41  	item->next = 0;
42  	item->prev = list->tail;
43  	if (list->tail != 0)
44  		list->tail->next = item;
45  	else
46  		list->head = item;
47  	list->tail = item;
48  }
49  
list_prepend(struct list * list,struct list_item * item)50  static inline void list_prepend(struct list *list, struct list_item *item)
51  {
52  	item->prev = 0;
53  	item->next = list->head;
54  	if (list->head == 0)
55  		list->tail = item;
56  	list->head = item;
57  }
58  
list_insert(struct list * list,struct list_item * after,struct list_item * item)59  static inline void list_insert(struct list *list, struct list_item *after, struct list_item *item)
60  {
61  	if (after == 0) {
62  		list_prepend(list, item);
63  		return;
64  	}
65  	item->prev = after;
66  	item->next = after->next;
67  	after->next = item;
68  	if (item->next)
69  		item->next->prev = item;
70  	if (list->tail == after)
71  		list->tail = item;
72  }
73  
list_remove(struct list * list,struct list_item * item)74  static inline void list_remove(struct list *list, struct list_item *item)
75  {
76  	if (item->next)
77  		item->next->prev = item->prev;
78  	if (list->head == item) {
79  		list->head = item->next;
80  		if (list->head == 0)
81  			list->tail = 0;
82  	} else {
83  		item->prev->next = item->next;
84  		if (list->tail == item)
85  			list->tail = item->prev;
86  	}
87  	item->prev = item->next = 0;
88  }
89  
list_pop(struct list * list)90  static inline struct list_item *list_pop(struct list *list)
91  {
92  	struct list_item *item;
93  	item = list->head;
94  	if (item == 0)
95  		return 0;
96  	list_remove(list, item);
97  	return item;
98  }
99  
list_last(struct list * list)100  static inline struct list_item *list_last(struct list *list)
101  {
102  	return list->tail;
103  }
104  
list_first(struct list * list)105  static inline struct list_item *list_first(struct list *list)
106  {
107  	return list->head;
108  }
109  
110  
list_next(struct list_item * item)111  static inline struct list_item *list_next(struct list_item *item)
112  {
113  	return item->next;
114  }
115  
116  #define list_push list_append
117  
118  #define list_for_each(_list, _iter) \
119    for (_iter = (_list)->head; (_iter) != 0; _iter = (_iter)->next)
120  
121  #define list_for_each_after(_node, _iter) \
122    for (_iter = (_node)->next; (_iter) != 0; _iter = (_iter)->next)
123  
124  #define list_for_each_safe(_list, _iter, _bkup) \
125    for (_iter = (_list)->head; (_iter) != 0 && ((_bkup = (_iter)->next) || 1); _iter = (_bkup))
126  
127  #define list_for_each_safe_after(_node, _iter, _bkup) \
128    for (_iter = (_node)->next; (_iter) != 0 && ((_bkup = (_iter)->next) || 1); _iter = (_bkup))
129  
130  #endif
131