Przeglądaj źródła

[list] Extend list-manipulation assertions to all list-handling functions

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 14 lat temu
rodzic
commit
295ba15bd6
1 zmienionych plików z 92 dodań i 82 usunięć
  1. 92
    82
      src/include/ipxe/list.h

+ 92
- 82
src/include/ipxe/list.h Wyświetl plik

@@ -14,35 +14,58 @@ FILE_LICENCE ( GPL2_ONLY );
14 14
 #include <stddef.h>
15 15
 #include <assert.h>
16 16
 
17
-/*
18
- * Simple doubly linked list implementation.
19
- *
20
- * Some of the internal functions ("__xxx") are useful when
21
- * manipulating whole lists rather than single entries, as
22
- * sometimes we already know the next/prev entries and we can
23
- * generate better code by using them directly rather than
24
- * using the generic single-entry routines.
25
- */
26
-
17
+/** A doubly-linked list entry (or list head) */
27 18
 struct list_head {
19
+	/** Next list entry */
28 20
 	struct list_head *next;
21
+	/** Previous list entry */
29 22
 	struct list_head *prev;
30 23
 };
31 24
 
32
-#define LIST_HEAD_INIT( name ) { &(name), &(name) }
25
+/**
26
+ * Initialise a static list head
27
+ *
28
+ * @v list		List head
29
+ */
30
+#define LIST_HEAD_INIT( list ) { &(list), &(list) }
33 31
 
34
-#define LIST_HEAD( name ) \
35
-	struct list_head name = LIST_HEAD_INIT ( name )
32
+/**
33
+ * Declare a static list head
34
+ *
35
+ * @v list		List head
36
+ */
37
+#define LIST_HEAD( list ) \
38
+	struct list_head list = LIST_HEAD_INIT ( list )
36 39
 
37
-#define INIT_LIST_HEAD( ptr ) do { \
38
-	(ptr)->next = (ptr); (ptr)->prev = (ptr); \
39
-} while ( 0 )
40
+/**
41
+ * Initialise a list head
42
+ *
43
+ * @v list		List head
44
+ */
45
+#define INIT_LIST_HEAD( list ) do {			\
46
+	(list)->next = (list);				\
47
+	(list)->prev = (list);				\
48
+	} while ( 0 )
40 49
 
41
-/*
42
- * Insert a new entry between two known consecutive entries.
50
+/**
51
+ * Check a list entry or list head is valid
43 52
  *
44
- * This is only for internal list manipulation where we know
45
- * the prev/next entries already!
53
+ * @v list		List entry or head
54
+ */
55
+#define list_check( list ) ( {				\
56
+	assert ( (list) != NULL );			\
57
+	assert ( (list)->prev != NULL );		\
58
+	assert ( (list)->next != NULL );		\
59
+	assert ( (list)->next->prev == (list) );	\
60
+	assert ( (list)->prev->next == (list) );	\
61
+	} )
62
+
63
+/**
64
+ * Insert a list entry between two known consecutive entries
65
+ *
66
+ * @v new		New list entry
67
+ * @v prev		Previous list entry
68
+ * @v next		Next list entry
46 69
  */
47 70
 static inline void __list_add ( struct list_head *new,
48 71
 				struct list_head *prev,
@@ -56,49 +79,40 @@ static inline void __list_add ( struct list_head *new,
56 79
 /**
57 80
  * Add a new entry to the head of a list
58 81
  *
59
- * @v new	New entry to be added
60
- * @v head	List head to add it after
61
- *
62
- * Insert a new entry after the specified head.  This is good for
63
- * implementing stacks.
82
+ * @v new		New entry to be added
83
+ * @v head		List head, or entry after which to add the new entry
64 84
  */
65 85
 static inline void list_add ( struct list_head *new, struct list_head *head ) {
66 86
 	__list_add ( new, head, head->next );
67 87
 }
68 88
 #define list_add( new, head ) do {			\
69
-	assert ( (head)->next->prev == (head) );	\
70
-	assert ( (head)->prev->next == (head) );	\
89
+	list_check ( (head) );				\
71 90
 	list_add ( (new), (head) );			\
72 91
 	} while ( 0 )
73 92
 
74 93
 /**
75 94
  * Add a new entry to the tail of a list
76 95
  *
77
- * @v new	New entry to be added
78
- * @v head	List head to add it before
79
- *
80
- * Insert a new entry before the specified head.  This is useful for
81
- * implementing queues.
96
+ * @v new		New entry to be added
97
+ * @v head		List head, or entry before which to add the new entry
82 98
  */
83 99
 static inline void list_add_tail ( struct list_head *new,
84 100
 				   struct list_head *head ) {
85 101
 	__list_add ( new, head->prev, head );
86 102
 }
87 103
 #define list_add_tail( new, head ) do {			\
88
-	assert ( (head)->next->prev == (head) );	\
89
-	assert ( (head)->prev->next == (head) );	\
104
+	list_check ( (head) );				\
90 105
 	list_add_tail ( (new), (head) );		\
91 106
 	} while ( 0 )
92 107
 
93
-/*
94
- * Delete a list entry by making the prev/next entries
95
- * point to each other.
108
+/**
109
+ * Delete a list entry between two known consecutive entries
96 110
  *
97
- * This is only for internal list manipulation where we know
98
- * the prev/next entries already!
111
+ * @v prev		Previous list entry
112
+ * @v next		Next list entry
99 113
  */
100
-static inline void __list_del ( struct list_head * prev,
101
-				struct list_head * next ) {
114
+static inline void __list_del ( struct list_head *prev,
115
+				struct list_head *next ) {
102 116
 	next->prev = prev;
103 117
 	prev->next = next;
104 118
 }
@@ -106,84 +120,80 @@ static inline void __list_del ( struct list_head * prev,
106 120
 /**
107 121
  * Delete an entry from a list
108 122
  *
109
- * @v entry	Element to delete from the list
123
+ * @v list		List entry
110 124
  *
111 125
  * Note that list_empty() on entry does not return true after this;
112 126
  * the entry is in an undefined state.
113 127
  */
114
-static inline void list_del ( struct list_head *entry ) {
115
-	__list_del ( entry->prev, entry->next );
128
+static inline void list_del ( struct list_head *list ) {
129
+	__list_del ( list->prev, list->next );
116 130
 }
117
-#define list_del( entry ) do {				\
118
-	assert ( (entry)->prev != NULL );		\
119
-	assert ( (entry)->next != NULL );		\
120
-	assert ( (entry)->next->prev == (entry) );	\
121
-	assert ( (entry)->prev->next == (entry) );	\
122
-	list_del ( (entry) );				\
131
+#define list_del( list ) do {				\
132
+	list_check ( (list) );				\
133
+	list_del ( (list) );				\
123 134
 	} while ( 0 )
124 135
 
125 136
 /**
126 137
  * Test whether a list is empty
127 138
  *
128
- * @v head	List to test.
139
+ * @v list		List head
129 140
  */
130
-static inline int list_empty ( const struct list_head *head ) {
131
-	return head->next == head;
141
+static inline int list_empty ( const struct list_head *list ) {
142
+	return ( list->next == list );
132 143
 }
144
+#define list_empty( list ) ( {				\
145
+	list_check ( (list) );				\
146
+	list_empty ( (list) ); } )
133 147
 
134 148
 /**
135
- * Get the containing struct for this entry
136
- *
137
- * @v ptr	The struct list_head pointer
138
- * @v type	The type of the struct this is embedded in
139
- * @v member	The name of the list_struct within the struct
140
- */
141
-#define list_entry( ptr, type, member ) \
142
-	container_of ( ptr, type, member )
143
-
144
-/**
145
- * Iterate over a list
149
+ * Get the container of a list entry
146 150
  *
147
- * @v pos	The &struct list_head to use as a loop counter
148
- * @v head	The head for your list
151
+ * @v list		List entry
152
+ * @v type		Containing type
153
+ * @v member		Name of list field within containing type
154
+ * @ret container	Containing object
149 155
  */
150
-#define list_for_each( pos, head ) \
151
-	for ( pos = (head)->next; pos != (head); pos = pos->next )
156
+#define list_entry( list, type, member ) ( {		\
157
+	list_check ( (list) );				\
158
+	container_of ( list, type, member ); } )
152 159
 
153 160
 /**
154 161
  * Iterate over entries in a list
155 162
  *
156
- * @v pos	The type * to use as a loop counter
157
- * @v head	The head for your list
158
- * @v member	The name of the list_struct within the struct
163
+ * @v pos		Iterator
164
+ * @v head		List head
165
+ * @v member		Name of list field within iterator's type
159 166
  */
160 167
 #define list_for_each_entry( pos, head, member )			      \
161
-	for ( pos = list_entry ( (head)->next, typeof ( *pos ), member );     \
168
+	for ( list_check ( (head) ),					      \
169
+	      pos = list_entry ( (head)->next, typeof ( *pos ), member );     \
162 170
 	      &pos->member != (head);					      \
163 171
 	      pos = list_entry ( pos->member.next, typeof ( *pos ), member ) )
164 172
 
165 173
 /**
166 174
  * Iterate over entries in a list in reverse order
167 175
  *
168
- * @v pos	The type * to use as a loop counter
169
- * @v head	The head for your list
170
- * @v member	The name of the list_struct within the struct
176
+ * @v pos		Iterator
177
+ * @v head		List head
178
+ * @v member		Name of list field within iterator's type
171 179
  */
172 180
 #define list_for_each_entry_reverse( pos, head, member )		      \
173
-	for ( pos = list_entry ( (head)->prev, typeof ( *pos ), member );     \
181
+	for ( list_check ( (head) ),					      \
182
+	      pos = list_entry ( (head)->prev, typeof ( *pos ), member );     \
174 183
 	      &pos->member != (head);					      \
175 184
 	      pos = list_entry ( pos->member.prev, typeof ( *pos ), member ) )
176 185
 
177 186
 /**
178
- * Iterate over entries in a list, safe against deletion of entries
187
+ * Iterate over entries in a list, safe against deletion of the current entry
179 188
  *
180
- * @v pos	The type * to use as a loop counter
181
- * @v tmp	Another type * to use for temporary storage
182
- * @v head	The head for your list
183
- * @v member	The name of the list_struct within the struct
189
+ * @v pos		Iterator
190
+ * @v tmp		Temporary value (of same type as iterator)
191
+ * @v head		List head
192
+ * @v member		Name of list field within iterator's type
184 193
  */
185 194
 #define list_for_each_entry_safe( pos, tmp, head, member )		      \
186
-	for ( pos = list_entry ( (head)->next, typeof ( *pos ), member ),     \
195
+	for ( list_check ( (head) ),					      \
196
+	      pos = list_entry ( (head)->next, typeof ( *pos ), member ),     \
187 197
 	      tmp = list_entry ( pos->member.next, typeof ( *tmp ), member ); \
188 198
 	      &pos->member != (head);					      \
189 199
 	      pos = tmp,						      \

Ładowanie…
Anuluj
Zapisz