diff options
author | Luis R. Rodriguez <lrodriguez@atheros.com> | 2008-08-06 16:28:54 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-08-07 09:49:42 -0400 |
commit | 00e8a4da8cf0d7dba8cc4b0da28ea0f12dcf6b36 (patch) | |
tree | 66d6b18fbafd6f1887f7ab7246e98caff2dd720c | |
parent | 7d283aee50351ec19eaf654a8690d77c4e1dff50 (diff) |
list.h: add list_cut_position()
This adds list_cut_position() which lets you cut a list into
two lists given a pivot in the list.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | include/linux/list.h | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/include/linux/list.h b/include/linux/list.h index a886f27a1181..1d109e2ef0a9 100644 --- a/include/linux/list.h +++ b/include/linux/list.h | |||
@@ -214,6 +214,46 @@ static inline int list_is_singular(const struct list_head *head) | |||
214 | return !list_empty(head) && (head->next == head->prev); | 214 | return !list_empty(head) && (head->next == head->prev); |
215 | } | 215 | } |
216 | 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 | |||
217 | static inline void __list_splice(const struct list_head *list, | 257 | static inline void __list_splice(const struct list_head *list, |
218 | struct list_head *prev, | 258 | struct list_head *prev, |
219 | struct list_head *next) | 259 | struct list_head *next) |