/* Copyright (C) 2021,2022 fef . All rights reserved. */ #include #include #include #include #include #if CFG_DEBUG_CLIST #define CLIST_DEBUG_BLOCK #define CLIST_ASSERT(x) KASSERT(x) #else #define CLIST_DEBUG_BLOCK if (0) #define CLIST_ASSERT(x) ({}) #endif void clist_init(struct clist *head) { CLIST_DEBUG_BLOCK { if (head->next == head && head->prev == head) kprintf("clist_init(%p) called multiple times\n", head); } head->next = head; head->prev = head; } void clist_add(struct clist *head, struct clist *new) { CLIST_ASSERT(!sus_nil(head->next)); CLIST_ASSERT(!sus_nil(new)); head->prev->next = new; new->next = head; new->prev = head->prev; head->prev = new; } void clist_add_first(struct clist *head, struct clist *new) { head->next->prev = new; new->next = head->next; new->prev = head; head->next = new; } void clist_del(struct clist *node) { node->next->prev = node->prev; node->prev->next = node->next; CLIST_DEBUG_BLOCK { node->next = (struct clist *)CLIST_POISON_NEXT; node->prev = (struct clist *)CLIST_POISON_PREV; } } struct clist *clist_del_first(struct clist *head) { CLIST_ASSERT(!clist_is_empty(head)); struct clist *first = head->next; clist_del(first); return first; } struct clist *clist_del_last(struct clist *head) { CLIST_ASSERT(!clist_is_empty(head)); struct clist *last = head->prev; clist_del(last); return last; }