diff options
Diffstat (limited to 'include/linux/list.h')
-rw-r--r-- | include/linux/list.h | 91 |
1 files changed, 78 insertions, 13 deletions
diff --git a/include/linux/list.h b/include/linux/list.h index 139ec41d9c2e..db35ef02e745 100644 --- a/include/linux/list.h +++ b/include/linux/list.h | |||
@@ -61,14 +61,10 @@ extern void __list_add(struct list_head *new, | |||
61 | * Insert a new entry after the specified head. | 61 | * Insert a new entry after the specified head. |
62 | * This is good for implementing stacks. | 62 | * This is good for implementing stacks. |
63 | */ | 63 | */ |
64 | #ifndef CONFIG_DEBUG_LIST | ||
65 | static inline void list_add(struct list_head *new, struct list_head *head) | 64 | static inline void list_add(struct list_head *new, struct list_head *head) |
66 | { | 65 | { |
67 | __list_add(new, head, head->next); | 66 | __list_add(new, head, head->next); |
68 | } | 67 | } |
69 | #else | ||
70 | extern void list_add(struct list_head *new, struct list_head *head); | ||
71 | #endif | ||
72 | 68 | ||
73 | 69 | ||
74 | /** | 70 | /** |
@@ -218,22 +214,62 @@ static inline int list_is_singular(const struct list_head *head) | |||
218 | return !list_empty(head) && (head->next == head->prev); | 214 | return !list_empty(head) && (head->next == head->prev); |
219 | } | 215 | } |
220 | 216 | ||
217 | static inline void __list_cut_position(struct list_head *list, | ||
218 | struct list_head *head, struct list_head *entry) | ||
219 | { | ||
220 | struct list_head *new_first = entry->next; | ||
221 | list->next = head->next; | ||
222 | list->next->prev = list; | ||
223 | list->prev = entry; | ||
224 | entry->next = list; | ||
225 | head->next = new_first; | ||
226 | new_first->prev = head; | ||
227 | } | ||
228 | |||
229 | /** | ||
230 | * list_cut_position - cut a list into two | ||
231 | * @list: a new list to add all removed entries | ||
232 | * @head: a list with entries | ||
233 | * @entry: an entry within head, could be the head itself | ||
234 | * and if so we won't cut the list | ||
235 | * | ||
236 | * This helper moves the initial part of @head, up to and | ||
237 | * including @entry, from @head to @list. You should | ||
238 | * pass on @entry an element you know is on @head. @list | ||
239 | * should be an empty list or a list you do not care about | ||
240 | * losing its data. | ||
241 | * | ||
242 | */ | ||
243 | static inline void list_cut_position(struct list_head *list, | ||
244 | struct list_head *head, struct list_head *entry) | ||
245 | { | ||
246 | if (list_empty(head)) | ||
247 | return; | ||
248 | if (list_is_singular(head) && | ||
249 | (head->next != entry && head != entry)) | ||
250 | return; | ||
251 | if (entry == head) | ||
252 | INIT_LIST_HEAD(list); | ||
253 | else | ||
254 | __list_cut_position(list, head, entry); | ||
255 | } | ||
256 | |||
221 | static inline void __list_splice(const struct list_head *list, | 257 | static inline void __list_splice(const struct list_head *list, |
222 | struct list_head *head) | 258 | struct list_head *prev, |
259 | struct list_head *next) | ||
223 | { | 260 | { |
224 | struct list_head *first = list->next; | 261 | struct list_head *first = list->next; |
225 | struct list_head *last = list->prev; | 262 | struct list_head *last = list->prev; |
226 | struct list_head *at = head->next; | ||
227 | 263 | ||
228 | first->prev = head; | 264 | first->prev = prev; |
229 | head->next = first; | 265 | prev->next = first; |
230 | 266 | ||
231 | last->next = at; | 267 | last->next = next; |
232 | at->prev = last; | 268 | next->prev = last; |
233 | } | 269 | } |
234 | 270 | ||
235 | /** | 271 | /** |
236 | * list_splice - join two lists | 272 | * list_splice - join two lists, this is designed for stacks |
237 | * @list: the new list to add. | 273 | * @list: the new list to add. |
238 | * @head: the place to add it in the first list. | 274 | * @head: the place to add it in the first list. |
239 | */ | 275 | */ |
@@ -241,7 +277,19 @@ static inline void list_splice(const struct list_head *list, | |||
241 | struct list_head *head) | 277 | struct list_head *head) |
242 | { | 278 | { |
243 | if (!list_empty(list)) | 279 | if (!list_empty(list)) |
244 | __list_splice(list, head); | 280 | __list_splice(list, head, head->next); |
281 | } | ||
282 | |||
283 | /** | ||
284 | * list_splice_tail - join two lists, each list being a queue | ||
285 | * @list: the new list to add. | ||
286 | * @head: the place to add it in the first list. | ||
287 | */ | ||
288 | static inline void list_splice_tail(struct list_head *list, | ||
289 | struct list_head *head) | ||
290 | { | ||
291 | if (!list_empty(list)) | ||
292 | __list_splice(list, head->prev, head); | ||
245 | } | 293 | } |
246 | 294 | ||
247 | /** | 295 | /** |
@@ -255,7 +303,24 @@ static inline void list_splice_init(struct list_head *list, | |||
255 | struct list_head *head) | 303 | struct list_head *head) |
256 | { | 304 | { |
257 | if (!list_empty(list)) { | 305 | if (!list_empty(list)) { |
258 | __list_splice(list, head); | 306 | __list_splice(list, head, head->next); |
307 | INIT_LIST_HEAD(list); | ||
308 | } | ||
309 | } | ||
310 | |||
311 | /** | ||
312 | * list_splice_tail_init - join two lists and reinitialise the emptied list | ||
313 | * @list: the new list to add. | ||
314 | * @head: the place to add it in the first list. | ||
315 | * | ||
316 | * Each of the lists is a queue. | ||
317 | * The list at @list is reinitialised | ||
318 | */ | ||
319 | static inline void list_splice_tail_init(struct list_head *list, | ||
320 | struct list_head *head) | ||
321 | { | ||
322 | if (!list_empty(list)) { | ||
323 | __list_splice(list, head->prev, head); | ||
259 | INIT_LIST_HEAD(list); | 324 | INIT_LIST_HEAD(list); |
260 | } | 325 | } |
261 | } | 326 | } |