|
@@ -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
|
/**
|