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 /include/linux | |
| 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>
Diffstat (limited to 'include/linux')
| -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) |
