Переглянути джерело

[list] Reduce overall code size by externalising many list functions

Typical saving is 10-20 bytes in each file using list functions.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 11 роки тому
джерело
коміт
54a861a7bd
2 змінених файлів з 215 додано та 122 видалено
  1. 84
    0
      src/core/list.c
  2. 131
    122
      src/include/ipxe/list.h

+ 84
- 0
src/core/list.c Переглянути файл

@@ -0,0 +1,84 @@
1
+/*
2
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or (at your option) any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17
+ * 02110-1301, USA.
18
+ */
19
+
20
+FILE_LICENCE ( GPL2_OR_LATER );
21
+
22
+/** @file
23
+ *
24
+ * Linked lists
25
+ *
26
+ */
27
+
28
+#include <ipxe/list.h>
29
+
30
+void extern_list_add ( struct list_head *new, struct list_head *head ) {
31
+	inline_list_add ( new, head );
32
+}
33
+
34
+void extern_list_add_tail ( struct list_head *new, struct list_head *head ) {
35
+	inline_list_add_tail ( new, head );
36
+}
37
+
38
+void extern_list_del ( struct list_head *list ) {
39
+	inline_list_del ( list );
40
+}
41
+
42
+int extern_list_empty ( const struct list_head *list ) {
43
+	return inline_list_empty ( list );
44
+}
45
+
46
+int extern_list_is_singular ( const struct list_head *list ) {
47
+	return inline_list_is_singular ( list );
48
+}
49
+
50
+int extern_list_is_last ( const struct list_head *list,
51
+			  const struct list_head *head ) {
52
+	return inline_list_is_last ( list, head );
53
+}
54
+
55
+void extern_list_cut_position ( struct list_head *new,
56
+				struct list_head *list,
57
+				struct list_head *entry ) {
58
+	inline_list_cut_position ( new, list, entry );
59
+}
60
+
61
+void extern_list_splice ( const struct list_head *list,
62
+			  struct list_head *entry ) {
63
+	inline_list_splice ( list, entry );
64
+}
65
+
66
+void extern_list_splice_tail ( const struct list_head *list,
67
+			       struct list_head *entry ) {
68
+	inline_list_splice_tail ( list, entry );
69
+}
70
+
71
+void extern_list_splice_init ( struct list_head *list,
72
+			       struct list_head *entry ) {
73
+	inline_list_splice_init ( list, entry );
74
+}
75
+
76
+void extern_list_splice_tail_init ( struct list_head *list,
77
+				    struct list_head *entry ) {
78
+	inline_list_splice_tail_init ( list, entry );
79
+}
80
+
81
+int extern_list_contains ( struct list_head *entry,
82
+			   struct list_head *head ) {
83
+	return inline_list_contains ( entry, head );
84
+}

+ 131
- 122
src/include/ipxe/list.h Переглянути файл

@@ -42,9 +42,9 @@ struct list_head {
42 42
  *
43 43
  * @v list		List head
44 44
  */
45
-#define INIT_LIST_HEAD( list ) do {			\
46
-	(list)->next = (list);				\
47
-	(list)->prev = (list);				\
45
+#define INIT_LIST_HEAD( list ) do {				\
46
+	(list)->next = (list);					\
47
+	(list)->prev = (list);					\
48 48
 	} while ( 0 )
49 49
 
50 50
 /**
@@ -52,43 +52,35 @@ struct list_head {
52 52
  *
53 53
  * @v list		List entry or head
54 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) );	\
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 61
 	} )
62 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
69
- */
70
-static inline void __list_add ( struct list_head *new,
71
-				struct list_head *prev,
72
-				struct list_head *next ) {
73
-	next->prev = new;
74
-	new->next = next;
75
-	new->prev = prev;
76
-	prev->next = new;
77
-}
78
-
79 63
 /**
80 64
  * Add a new entry to the head of a list
81 65
  *
82 66
  * @v new		New entry to be added
83 67
  * @v head		List head, or entry after which to add the new entry
84 68
  */
85
-static inline void list_add ( struct list_head *new, struct list_head *head ) {
86
-	__list_add ( new, head, head->next );
87
-}
88
-#define list_add( new, head ) do {			\
89
-	list_check ( (head) );				\
90
-	list_add ( (new), (head) );			\
69
+#define list_add( new, head ) do {				\
70
+	list_check ( (head) );					\
71
+	extern_list_add ( (new), (head) );			\
91 72
 	} while ( 0 )
73
+static inline void inline_list_add ( struct list_head *new,
74
+				     struct list_head *head ) {
75
+	struct list_head *prev = head;
76
+	struct list_head *next = head->next;
77
+	next->prev = (new);
78
+	(new)->next = next;
79
+	(new)->prev = prev;
80
+	prev->next = (new);
81
+}
82
+extern void extern_list_add ( struct list_head *new,
83
+			      struct list_head *head );
92 84
 
93 85
 /**
94 86
  * Add a new entry to the tail of a list
@@ -96,26 +88,21 @@ static inline void list_add ( struct list_head *new, struct list_head *head ) {
96 88
  * @v new		New entry to be added
97 89
  * @v head		List head, or entry before which to add the new entry
98 90
  */
99
-static inline void list_add_tail ( struct list_head *new,
100
-				   struct list_head *head ) {
101
-	__list_add ( new, head->prev, head );
102
-}
103
-#define list_add_tail( new, head ) do {			\
104
-	list_check ( (head) );				\
105
-	list_add_tail ( (new), (head) );		\
91
+#define list_add_tail( new, head ) do {				\
92
+	list_check ( (head) );					\
93
+	extern_list_add_tail ( (new), (head) );			\
106 94
 	} while ( 0 )
107
-
108
-/**
109
- * Delete a list entry between two known consecutive entries
110
- *
111
- * @v prev		Previous list entry
112
- * @v next		Next list entry
113
- */
114
-static inline void __list_del ( struct list_head *prev,
115
-				struct list_head *next ) {
116
-	next->prev = prev;
117
-	prev->next = next;
95
+static inline void inline_list_add_tail ( struct list_head *new,
96
+					  struct list_head *head ) {
97
+	struct list_head *prev = head->prev;
98
+	struct list_head *next = head;
99
+	next->prev = (new);
100
+	(new)->next = next;
101
+	(new)->prev = prev;
102
+	prev->next = (new);
118 103
 }
104
+extern void extern_list_add_tail ( struct list_head *new,
105
+				   struct list_head *head );
119 106
 
120 107
 /**
121 108
  * Delete an entry from a list
@@ -125,37 +112,43 @@ static inline void __list_del ( struct list_head *prev,
125 112
  * Note that list_empty() on entry does not return true after this;
126 113
  * the entry is in an undefined state.
127 114
  */
128
-static inline void list_del ( struct list_head *list ) {
129
-	__list_del ( list->prev, list->next );
130
-}
131
-#define list_del( list ) do {				\
132
-	list_check ( (list) );				\
133
-	list_del ( (list) );				\
115
+#define list_del( list ) do {					\
116
+	list_check ( (list) );					\
117
+	inline_list_del ( (list) );				\
134 118
 	} while ( 0 )
119
+static inline void inline_list_del ( struct list_head *list ) {
120
+	struct list_head *next = (list)->next;
121
+	struct list_head *prev = (list)->prev;
122
+	next->prev = prev;
123
+	prev->next = next;
124
+}
125
+extern void extern_list_del ( struct list_head *list );
135 126
 
136 127
 /**
137 128
  * Test whether a list is empty
138 129
  *
139 130
  * @v list		List head
140 131
  */
141
-static inline int list_empty ( const struct list_head *list ) {
132
+#define list_empty( list ) ( {					\
133
+	list_check ( (list) );					\
134
+	inline_list_empty ( (list) ); } )
135
+static inline int inline_list_empty ( const struct list_head *list ) {
142 136
 	return ( list->next == list );
143 137
 }
144
-#define list_empty( list ) ( {				\
145
-	list_check ( (list) );				\
146
-	list_empty ( (list) ); } )
138
+extern int extern_list_empty ( const struct list_head *list );
147 139
 
148 140
 /**
149 141
  * Test whether a list has just one entry
150 142
  *
151 143
  * @v list		List to test
152 144
  */
153
-static inline int list_is_singular ( const struct list_head *list ) {
145
+#define list_is_singular( list ) ( {				\
146
+	list_check ( (list) );					\
147
+	inline_list_is_singular ( (list) ); } )
148
+static inline int inline_list_is_singular ( const struct list_head *list ) {
154 149
 	return ( ( ! list_empty ( list ) ) && ( list->next == list->prev ) );
155 150
 }
156
-#define list_is_singular( list ) ( {			\
157
-	list_check ( (list) );				\
158
-	list_is_singular ( (list) ); } )
151
+extern int extern_list_is_singular ( const struct list_head *list );
159 152
 
160 153
 /**
161 154
  * Test whether an entry is the last entry in list
@@ -163,14 +156,16 @@ static inline int list_is_singular ( const struct list_head *list ) {
163 156
  * @v list		List entry to test
164 157
  * @v head		List head
165 158
  */
166
-static inline int list_is_last ( const struct list_head *list,
167
-				 const struct list_head *head ) {
159
+#define list_is_last( list, head ) ( {				\
160
+	list_check ( (list) );					\
161
+	list_check ( (head) );					\
162
+	inline_list_is_last ( (list), (head) ); } )
163
+static inline int inline_list_is_last ( const struct list_head *list,
164
+					const struct list_head *head ) {
168 165
 	return ( list->next == head );
169 166
 }
170
-#define list_is_last( list, head ) ( {			\
171
-	list_check ( (list) );				\
172
-	list_check ( (head) );				\
173
-	list_is_last ( (list), (head) ); } )
167
+extern int extern_list_is_last ( const struct list_head *list,
168
+				 const struct list_head *head );
174 169
 
175 170
 /**
176 171
  * Cut a list into two
@@ -183,9 +178,16 @@ static inline int list_is_last ( const struct list_head *list,
183 178
  * @c new, which should be an empty list.  @c entry may be equal to @c
184 179
  * list, in which case no entries are moved.
185 180
  */
186
-static inline void list_cut_position ( struct list_head *new,
187
-				       struct list_head *list,
188
-				       struct list_head *entry ) {
181
+#define list_cut_position( new, list, entry ) do {		\
182
+	list_check ( (new) );					\
183
+	assert ( list_empty ( (new) ) );			\
184
+	list_check ( (list) );					\
185
+	list_check ( (entry) );					\
186
+	extern_list_cut_position ( (new), (list), (entry) );	\
187
+	} while ( 0 )
188
+static inline void inline_list_cut_position ( struct list_head *new,
189
+					      struct list_head *list,
190
+					      struct list_head *entry ) {
189 191
 	struct list_head *first = entry->next;
190 192
 
191 193
 	if ( list != entry ) {
@@ -197,13 +199,9 @@ static inline void list_cut_position ( struct list_head *new,
197 199
 		list->next->prev = list;
198 200
 	}
199 201
 }
200
-#define list_cut_position( new, list, entry ) do {	\
201
-	list_check ( (new) );				\
202
-	assert ( list_empty ( (new) ) );		\
203
-	list_check ( (list) );				\
204
-	list_check ( (entry) );				\
205
-	list_cut_position ( (new), (list), (entry) );	\
206
-	} while ( 0 )
202
+extern void extern_list_cut_position ( struct list_head *new,
203
+				       struct list_head *list,
204
+				       struct list_head *entry );
207 205
 
208 206
 /**
209 207
  * Move all entries from one list into another list
@@ -215,8 +213,13 @@ static inline void list_cut_position ( struct list_head *new,
215 213
  * list is left in an undefined state; use @c list_splice_init() if
216 214
  * you want @c list to become an empty list.
217 215
  */
218
-static inline void list_splice ( const struct list_head *list,
219
-				 struct list_head *entry ) {
216
+#define list_splice( list, entry ) do {				\
217
+	list_check ( (list) );					\
218
+	list_check ( (entry) );					\
219
+	extern_list_splice ( (list), (entry) );			\
220
+	} while ( 0 )
221
+static inline void inline_list_splice ( const struct list_head *list,
222
+					struct list_head *entry ) {
220 223
 	struct list_head *first = list->next;
221 224
 	struct list_head *last = list->prev;
222 225
 
@@ -227,11 +230,8 @@ static inline void list_splice ( const struct list_head *list,
227 230
 		first->prev->next = first;
228 231
 	}
229 232
 }
230
-#define list_splice( list, entry ) do {			\
231
-	list_check ( (list) );				\
232
-	list_check ( (entry) );				\
233
-	list_splice ( (list), (entry) );		\
234
-	} while ( 0 )
233
+extern void extern_list_splice ( const struct list_head *list,
234
+				 struct list_head *entry );
235 235
 
236 236
 /**
237 237
  * Move all entries from one list into another list
@@ -243,8 +243,13 @@ static inline void list_splice ( const struct list_head *list,
243 243
  * list is left in an undefined state; use @c list_splice_tail_init() if
244 244
  * you want @c list to become an empty list.
245 245
  */
246
-static inline void list_splice_tail ( const struct list_head *list,
247
-				      struct list_head *entry ) {
246
+#define list_splice_tail( list, entry ) do {			\
247
+	list_check ( (list) );					\
248
+	list_check ( (entry) );					\
249
+	extern_list_splice_tail ( (list), (entry) );		\
250
+	} while ( 0 )
251
+static inline void inline_list_splice_tail ( const struct list_head *list,
252
+					     struct list_head *entry ) {
248 253
 	struct list_head *first = list->next;
249 254
 	struct list_head *last = list->prev;
250 255
 
@@ -255,11 +260,8 @@ static inline void list_splice_tail ( const struct list_head *list,
255 260
 		last->next->prev = last;
256 261
 	}
257 262
 }
258
-#define list_splice_tail( list, entry ) do {		\
259
-	list_check ( (list) );				\
260
-	list_check ( (entry) );				\
261
-	list_splice_tail ( (list), (entry) );		\
262
-	} while ( 0 )
263
+extern void extern_list_splice_tail ( const struct list_head *list,
264
+				      struct list_head *entry );
263 265
 
264 266
 /**
265 267
  * Move all entries from one list into another list and reinitialise empty list
@@ -269,16 +271,18 @@ static inline void list_splice_tail ( const struct list_head *list,
269 271
  *
270 272
  * All entries from @c list are inserted after @c entry.
271 273
  */
272
-static inline void list_splice_init ( struct list_head *list,
273
-				      struct list_head *entry ) {
274
+#define list_splice_init( list, entry ) do {			\
275
+	list_check ( (list) );					\
276
+	list_check ( (entry) );					\
277
+	extern_list_splice_init ( (list), (entry) );		\
278
+	} while ( 0 )
279
+static inline void inline_list_splice_init ( struct list_head *list,
280
+					     struct list_head *entry ) {
274 281
 	list_splice ( list, entry );
275 282
 	INIT_LIST_HEAD ( list );
276 283
 }
277
-#define list_splice_init( list, entry ) do {			\
278
-	list_check ( (list) );				\
279
-	list_check ( (entry) );				\
280
-	list_splice_init ( (list), (entry) );		\
281
-	} while ( 0 )
284
+extern void extern_list_splice_init ( struct list_head *list,
285
+				      struct list_head *entry );
282 286
 
283 287
 /**
284 288
  * Move all entries from one list into another list and reinitialise empty list
@@ -288,16 +292,19 @@ static inline void list_splice_init ( struct list_head *list,
288 292
  *
289 293
  * All entries from @c list are inserted before @c entry.
290 294
  */
291
-static inline void list_splice_tail_init ( struct list_head *list,
292
-					   struct list_head *entry ) {
295
+#define list_splice_tail_init( list, entry ) do {		\
296
+	list_check ( (list) );					\
297
+	list_check ( (entry) );					\
298
+	extern_list_splice_tail_init ( (list), (entry) );	\
299
+	} while ( 0 )
300
+
301
+static inline void inline_list_splice_tail_init ( struct list_head *list,
302
+						  struct list_head *entry ) {
293 303
 	list_splice_tail ( list, entry );
294 304
 	INIT_LIST_HEAD ( list );
295 305
 }
296
-#define list_splice_tail_init( list, entry ) do {	\
297
-	list_check ( (list) );				\
298
-	list_check ( (entry) );				\
299
-	list_splice_tail_init ( (list), (entry) );	\
300
-	} while ( 0 )
306
+extern void extern_list_splice_tail_init ( struct list_head *list,
307
+					   struct list_head *entry );
301 308
 
302 309
 /**
303 310
  * Get the container of a list entry
@@ -307,8 +314,8 @@ static inline void list_splice_tail_init ( struct list_head *list,
307 314
  * @v member		Name of list field within containing type
308 315
  * @ret container	Containing object
309 316
  */
310
-#define list_entry( list, type, member ) ( {		\
311
-	list_check ( (list) );				\
317
+#define list_entry( list, type, member ) ( {			\
318
+	list_check ( (list) );					\
312 319
 	container_of ( list, type, member ); } )
313 320
 
314 321
 /**
@@ -319,9 +326,9 @@ static inline void list_splice_tail_init ( struct list_head *list,
319 326
  * @v member		Name of list field within containing type
320 327
  * @ret first		First list entry, or NULL
321 328
  */
322
-#define list_first_entry( list, type, member )		\
323
-	( list_empty ( (list) ) ?			\
324
-	  ( type * ) NULL :				\
329
+#define list_first_entry( list, type, member )			\
330
+	( list_empty ( (list) ) ?				\
331
+	  ( type * ) NULL :					\
325 332
 	  list_entry ( (list)->next, type, member ) )
326 333
 
327 334
 /**
@@ -332,9 +339,9 @@ static inline void list_splice_tail_init ( struct list_head *list,
332 339
  * @v member		Name of list field within containing type
333 340
  * @ret first		First list entry, or NULL
334 341
  */
335
-#define list_last_entry( list, type, member )		\
336
-	( list_empty ( (list) ) ?			\
337
-	  ( type * ) NULL :				\
342
+#define list_last_entry( list, type, member )			\
343
+	( list_empty ( (list) ) ?				\
344
+	  ( type * ) NULL :					\
338 345
 	  list_entry ( (list)->prev, type, member ) )
339 346
 
340 347
 /**
@@ -424,8 +431,12 @@ static inline void list_splice_tail_init ( struct list_head *list,
424 431
  * @v head		List head
425 432
  * @ret present		List contains specified entry
426 433
  */
427
-static inline int list_contains ( struct list_head *entry,
428
-				  struct list_head *head ) {
434
+#define list_contains( entry, head ) ( {			\
435
+	list_check ( (head) );					\
436
+	list_check ( (entry) );					\
437
+	extern_list_contains ( (entry), (head) ); } )
438
+static inline int inline_list_contains ( struct list_head *entry,
439
+					 struct list_head *head ) {
429 440
 	struct list_head *tmp;
430 441
 
431 442
 	list_for_each ( tmp, head ) {
@@ -434,10 +445,8 @@ static inline int list_contains ( struct list_head *entry,
434 445
 	}
435 446
 	return 0;
436 447
 }
437
-#define list_contains( entry, head ) ( {		\
438
-	list_check ( (head) );				\
439
-	list_check ( (entry) );				\
440
-	list_contains ( (entry), (head) ); } )
448
+extern int extern_list_contains ( struct list_head *entry,
449
+				  struct list_head *head );
441 450
 
442 451
 /**
443 452
  * Test if list contains a specified entry
@@ -446,7 +455,7 @@ static inline int list_contains ( struct list_head *entry,
446 455
  * @v head		List head
447 456
  * @ret present		List contains specified entry
448 457
  */
449
-#define list_contains_entry( entry, head, member )	\
458
+#define list_contains_entry( entry, head, member )		\
450 459
 	list_contains ( &(entry)->member, (head) )
451 460
 
452 461
 /**

Завантаження…
Відмінити
Зберегти