Add alist_merge_tail to efficiently merge two lists

Empties the "source" list, moving its contents to the tail of the
"destination" list.
This commit is contained in:
Andrei Alexeyev 2020-03-31 22:09:06 +03:00
parent 09d1a65faf
commit b902e90229
No known key found for this signature in database
GPG key ID: 363707CD4C7FE8A4
3 changed files with 24 additions and 3 deletions

View file

@ -861,9 +861,7 @@ CoTask *_cosched_new_task(CoSched *sched, CoTaskFunc func, void *arg, bool is_su
}
uint cosched_run_tasks(CoSched *sched) {
for(CoTask *t; (t = alist_pop(&sched->pending_tasks));) {
alist_append(&sched->tasks, t);
}
alist_merge_tail(&sched->tasks, &sched->pending_tasks);
uint ran = 0;

View file

@ -317,6 +317,25 @@ List* alist_pop(ListAnchor *list) {
return alist_unlink(list, list->first);
}
#undef alist_merge_tail
void alist_merge_tail(ListAnchor *dest, ListAnchor *src) {
if(src->first) {
src->first->prev = dest->last;
if(dest->last) {
assume(dest->first != NULL);
dest->last->next = src->first;
} else {
assume(dest->first == NULL);
dest->first = src->first;
}
dest->last = src->last;
src->first = NULL;
src->last = NULL;
}
}
#undef list_foreach
void* list_foreach(List **dest, ListForeachCallback callback, void *arg) {
void *ret = NULL;

View file

@ -92,6 +92,7 @@ List* alist_insert_at_priority_head(ListAnchor *list, List *elem, int prio, List
List* alist_insert_at_priority_tail(ListAnchor *list, List *elem, int prio, ListPriorityFunc prio_func) attr_hot attr_nonnull(1, 2, 4);
List* alist_pop(ListAnchor *list) attr_nonnull(1);
List* alist_unlink(ListAnchor *list, List *elem) attr_nonnull(1, 2);
void alist_merge_tail(ListAnchor *dest, ListAnchor *src) attr_nonnull(1, 2);
void* alist_foreach(ListAnchor *list, ListAnchorForeachCallback callback, void *arg) attr_nonnull(1, 2);
void* alist_callback_free_element(ListAnchor *list, List *elem, void *arg);
void alist_free_all(ListAnchor *list) attr_nonnull(1);
@ -179,6 +180,9 @@ ListContainer* list_wrap_container(void *data) attr_returns_allocated;
#define alist_unlink(dest,elem) \
(LIST_CAST_RETURN(elem, alist_unlink(LIST_ANCHOR_CAST(dest), LIST_CAST(elem))))
#define alist_merge_tail(dest,src) \
alist_merge_tail(LIST_ANCHOR_CAST(dest), LIST_ANCHOR_CAST(src))
#define list_foreach(dest,callback,arg) \
list_foreach(LIST_CAST_2(dest), callback, arg)