void list_destroy(List l) { ListIterator i, iTmp; ListNode p, pTmp; assert(l != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); i = l->iNext; while (i) { assert(i->magic == LIST_MAGIC); iTmp = i->iNext; assert(i->magic = 1); /* clear magic via assert abuse */ list_iterator_free(i); i = iTmp; } p = l->head; while (p) { pTmp = p->next; if (p->data && l->fDel) l->fDel(p->data); list_node_free(p); p = pTmp; } assert(l->magic = 1); /* clear magic via assert abuse */ list_mutex_unlock(&l->mutex); list_mutex_destroy(&l->mutex); list_free(l); return; }
static void * list_alloc_aux (int size, void *pfreelist) { /* Allocates an object of [size] bytes from the freelist [*pfreelist]. * Memory is added to the freelist in chunks of size LIST_ALLOC. * Returns a ptr to the object, or NULL if the memory request fails. */ void **px; void **pfree = pfreelist; void **plast; assert(sizeof(char) == 1); assert(size >= sizeof(void *)); assert(pfreelist != NULL); assert(LIST_ALLOC > 0); list_mutex_lock(&list_free_lock); if (!*pfree) { if ((*pfree = malloc(LIST_ALLOC * size))) { px = *pfree; plast = (void **) ((char *) *pfree + ((LIST_ALLOC - 1) * size)); while (px < plast) *px = (char *) px + size, px = *px; *plast = NULL; } } if ((px = *pfree)) *pfree = *px; else errno = ENOMEM; list_mutex_unlock(&list_free_lock); return(px); }
int list_delete_all(List l, ListFindF f, void *key) { ListNode *pp; void *v; int n = 0; assert(l != NULL); assert(f != NULL); assert(key != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); pp = &l->head; while (*pp) { if (f((*pp)->data, key)) { if ((v = list_node_destroy(l, pp))) { if (l->fDel) l->fDel(v); n++; } } else { pp = &(*pp)->next; } } list_mutex_unlock(&l->mutex); return(n); }
static void list_free(List l) { list_mutex_lock(&freeListsLock); l->iNext = (ListIterator) freeLists; freeLists = l; list_mutex_unlock(&freeListsLock); return; }
static void list_node_free(ListNode p) { list_mutex_lock(&freeListNodesLock); p->next = freeListNodes; freeListNodes = p; list_mutex_unlock(&freeListNodesLock); return; }
static void list_iterator_free(ListIterator i) { list_mutex_lock(&freeListIteratorsLock); i->iNext = freeListIterators; freeListIterators = i; list_mutex_unlock(&freeListIteratorsLock); return; }
int list_count(List l) { int n; assert(l != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); n = l->count; list_mutex_unlock(&l->mutex); return(n); }
void * list_dequeue(List l) { void *v; assert(l != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); v = list_node_destroy(l, &l->head); list_mutex_unlock(&l->mutex); return(v); }
void * list_peek(List l) { void *v; assert(l != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); v = (l->head) ? l->head->data : NULL; list_mutex_unlock(&l->mutex); return(v); }
void list_iterator_reset(ListIterator i) { assert(i != NULL); assert(i->magic == LIST_MAGIC); list_mutex_lock(&i->list->mutex); assert(i->list->magic == LIST_MAGIC); i->pos = i->list->head; i->prev = &i->list->head; list_mutex_unlock(&i->list->mutex); return; }
void * list_push(List l, void *x) { void *v; assert(l != NULL); assert(x != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); v = list_node_create(l, &l->head, x); list_mutex_unlock(&l->mutex); return(v); }
void * list_enqueue(List l, void *x) { void *v; assert(l != NULL); assert(x != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); v = list_node_create(l, l->tail, x); list_mutex_unlock(&l->mutex); return(v); }
void * list_insert(ListIterator i, void *x) { void *v; assert(i != NULL); assert(x != NULL); assert(i->magic == LIST_MAGIC); list_mutex_lock(&i->list->mutex); assert(i->list->magic == LIST_MAGIC); v = list_node_create(i->list, i->prev, x); list_mutex_unlock(&i->list->mutex); return(v); }
void * list_remove(ListIterator i) { void *v = NULL; assert(i != NULL); assert(i->magic == LIST_MAGIC); list_mutex_lock(&i->list->mutex); assert(i->list->magic == LIST_MAGIC); if (*i->prev != i->pos) v = list_node_destroy(i->list, i->prev); list_mutex_unlock(&i->list->mutex); return(v); }
void * list_next(ListIterator i) { ListNode p; assert(i != NULL); assert(i->magic == LIST_MAGIC); list_mutex_lock(&i->list->mutex); assert(i->list->magic == LIST_MAGIC); if ((p = i->pos)) i->pos = p->next; if (*i->prev != p) i->prev = &(*i->prev)->next; list_mutex_unlock(&i->list->mutex); return(p ? p->data : NULL); }
static void list_free_aux (void *x, void *pfreelist) { /* Frees the object [x], returning it to the freelist [*pfreelist]. */ void **px = x; void **pfree = pfreelist; assert(x != NULL); assert(pfreelist != NULL); list_mutex_lock(&list_free_lock); *px = *pfree; *pfree = px; list_mutex_unlock(&list_free_lock); return; }
ListIterator list_iterator_create(List l) { ListIterator i; assert(l != NULL); if (!(i = list_iterator_alloc())) return(out_of_memory()); i->list = l; list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); i->pos = l->head; i->prev = &l->head; i->iNext = l->iNext; l->iNext = i; list_mutex_unlock(&l->mutex); assert(i->magic = LIST_MAGIC); /* set magic via assert abuse */ return(i); }
void list_sort (List l, ListCmpF f) { /* Note: Time complexity O(n^2). */ ListNode *pp, *ppPrev, *ppPos, pTmp; ListIterator i; assert(l != NULL); assert(f != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); if (l->count > 1) { ppPrev = &l->head; pp = &(*ppPrev)->next; while (*pp) { if (f((*pp)->data, (*ppPrev)->data) < 0) { ppPos = &l->head; while (f((*pp)->data, (*ppPos)->data) >= 0) ppPos = &(*ppPos)->next; pTmp = (*pp)->next; (*pp)->next = *ppPos; *ppPos = *pp; *pp = pTmp; if (ppPrev == ppPos) ppPrev = &(*ppPrev)->next; } else { ppPrev = pp; pp = &(*pp)->next; } } l->tail = pp; for (i=l->iNext; i; i=i->iNext) { assert(i->magic == LIST_MAGIC); i->pos = i->list->head; i->prev = &i->list->head; } } list_mutex_unlock(&l->mutex); return; }
void * list_find_first(List l, ListFindF f, void *key) { ListNode p; void *v = NULL; assert(l != NULL); assert(f != NULL); assert(key != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); for (p=l->head; p; p=p->next) { if (f(p->data, key)) { v = p->data; break; } } list_mutex_unlock(&l->mutex); return(v); }
ListIterator list_iterator_create (List l) { ListIterator i; assert(l != NULL); if (!(i = list_iterator_alloc())) return(lsd_nomem_error(__FILE__, __LINE__, "list iterator create")); i->list = l; list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); i->pos = l->head; i->prev = &l->head; i->iNext = l->iNext; l->iNext = i; assert(i->magic = LIST_MAGIC); /* set magic via assert abuse */ list_mutex_unlock(&l->mutex); return(i); }
int list_for_each (List l, ListForF f, void *arg) { ListNode p; int n = 0; assert(l != NULL); assert(f != NULL); list_mutex_lock(&l->mutex); assert(l->magic == LIST_MAGIC); for (p=l->head; p; p=p->next) { n++; if (f(p->data, arg) < 0) { n = -n; break; } } list_mutex_unlock(&l->mutex); return(n); }
void list_iterator_destroy(ListIterator i) { ListIterator *pi; assert(i != NULL); assert(i->magic == LIST_MAGIC); list_mutex_lock(&i->list->mutex); assert(i->list->magic == LIST_MAGIC); for (pi=&i->list->iNext; *pi; pi=&(*pi)->iNext) { assert((*pi)->magic == LIST_MAGIC); if (*pi == i) { *pi = (*pi)->iNext; break; } } list_mutex_unlock(&i->list->mutex); assert(i->magic = 1); /* clear magic via assert abuse */ list_iterator_free(i); return; }
static ListIterator list_iterator_alloc(void) { ListIterator i; ListIterator last; list_mutex_lock(&freeListIteratorsLock); if (!freeListIterators) { freeListIterators = malloc(LIST_ALLOC * sizeof(struct listIterator)); if (freeListIterators) { last = freeListIterators + LIST_ALLOC - 1; for (i=freeListIterators; i<last; i++) i->iNext = i + 1; last->iNext = NULL; } } if ((i = freeListIterators)) freeListIterators = freeListIterators->iNext; list_mutex_unlock(&freeListIteratorsLock); return(i); }
static ListNode list_node_alloc(void) { ListNode p; ListNode last; list_mutex_lock(&freeListNodesLock); if (!freeListNodes) { freeListNodes = malloc(LIST_ALLOC * sizeof(struct listNode)); if (freeListNodes) { last = freeListNodes + LIST_ALLOC - 1; for (p=freeListNodes; p<last; p++) p->next = p + 1; last->next = NULL; } } if ((p = freeListNodes)) freeListNodes = freeListNodes->next; list_mutex_unlock(&freeListNodesLock); return(p); }
static List list_alloc(void) { List l; List last; list_mutex_lock(&freeListsLock); if (!freeLists) { freeLists = malloc(LIST_ALLOC * sizeof(struct list)); if (freeLists) { last = freeLists + LIST_ALLOC - 1; for (l=freeLists; l<last; l++) l->iNext = (ListIterator) (l + 1); last->iNext = NULL; } } if ((l = freeLists)) freeLists = (List) freeLists->iNext; list_mutex_unlock(&freeListsLock); return(l); }