diff --git a/src/common/list.c b/src/common/list.c index 4946d9a92d14213c826e57550ebc7efd1ddfc4d3..c7d239dba528b3ca5ccaf36170b8cd7dc9b7bb2d 100644 --- a/src/common/list.c +++ b/src/common/list.c @@ -59,7 +59,7 @@ /* ** Define slurm-specific aliases for use by plugins, see slurm_xlator.h ** for details. - */ +*/ strong_alias(list_create, slurm_list_create); strong_alias(list_destroy, slurm_list_destroy); strong_alias(list_is_empty, slurm_list_is_empty); @@ -94,13 +94,13 @@ strong_alias(list_install_fork_handlers, slurm_list_install_fork_handlers); #include <unistd.h> #ifdef WITH_LSD_FATAL_ERROR_FUNC # undef lsd_fatal_error - extern void lsd_fatal_error(char *file, int line, char *mesg); +extern void lsd_fatal_error(char *file, int line, char *mesg); #else /* !WITH_LSD_FATAL_ERROR_FUNC */ # ifndef lsd_fatal_error - static void lsd_fatal_error(char *file, int line, char *mesg) - { - log_fatal(file, line, mesg, strerror(errno)); - } +static void lsd_fatal_error(char *file, int line, char *mesg) +{ + log_fatal(file, line, mesg, strerror(errno)); +} # endif /* !lsd_fatal_error */ #endif /* !WITH_LSD_FATAL_ERROR_FUNC */ @@ -110,16 +110,16 @@ strong_alias(list_install_fork_handlers, slurm_list_install_fork_handlers); #ifdef WITH_LSD_NOMEM_ERROR_FUNC # undef lsd_nomem_error - extern void * lsd_nomem_error(char *file, int line, char *mesg); +extern void * lsd_nomem_error(char *file, int line, char *mesg); #else /* !WITH_LSD_NOMEM_ERROR_FUNC */ # ifndef lsd_nomem_error - static void * lsd_nomem_error(char *file, int line, char *mesg) - { +static void * lsd_nomem_error(char *file, int line, char *mesg) +{ - log_oom(file, line, mesg); - abort(); - return NULL; - } + log_oom(file, line, mesg); + abort(); + return NULL; +} # endif /* !lsd_nomem_error */ #endif /* !WITH_LSD_NOMEM_ERROR_FUNC */ @@ -156,31 +156,31 @@ strong_alias(list_install_fork_handlers, slurm_list_install_fork_handlers); ****************/ struct listNode { - void *data; /* node's data */ - struct listNode *next; /* next node in list */ + void *data; /* node's data */ + struct listNode *next; /* next node in list */ }; struct listIterator { - struct list *list; /* the list being iterated */ - struct listNode *pos; /* the next node to be iterated */ - struct listNode **prev; /* addr of 'next' ptr to prv It node */ - struct listIterator *iNext; /* iterator chain for list_destroy() */ + struct list *list; /* the list being iterated */ + struct listNode *pos; /* the next node to be iterated */ + struct listNode **prev; /* addr of 'next' ptr to prv It node */ + struct listIterator *iNext; /* iterator chain for list_destroy() */ #ifndef NDEBUG - unsigned int magic; /* sentinel for asserting validity */ + unsigned int magic; /* sentinel for asserting validity */ #endif /* !NDEBUG */ }; struct list { - struct listNode *head; /* head of the list */ - struct listNode **tail; /* addr of last node's 'next' ptr */ - struct listIterator *iNext; /* iterator chain for list_destroy() */ - ListDelF fDel; /* function to delete node data */ - int count; /* number of nodes in list */ + struct listNode *head; /* head of the list */ + struct listNode **tail; /* addr of last node's 'next' ptr */ + struct listIterator *iNext; /* iterator chain for list_destroy() */ + ListDelF fDel; /* function to delete node data */ + int count; /* number of nodes in list */ #ifdef WITH_PTHREADS - pthread_mutex_t mutex; /* mutex to protect access to list */ + pthread_mutex_t mutex; /* mutex to protect access to list */ #endif /* WITH_PTHREADS */ #ifndef NDEBUG - unsigned int magic; /* sentinel for asserting validity */ + unsigned int magic; /* sentinel for asserting validity */ #endif /* !NDEBUG */ }; @@ -223,48 +223,48 @@ static pthread_mutex_t list_free_lock = PTHREAD_MUTEX_INITIALIZER; #ifdef WITH_PTHREADS -# define list_mutex_init(mutex) \ - do { \ - int e = pthread_mutex_init(mutex, NULL); \ - if (e != 0) { \ - errno = e; \ - lsd_fatal_error(__FILE__, __LINE__, "list mutex init"); \ - abort(); \ - } \ - } while (0) - -# define list_mutex_lock(mutex) \ - do { \ - int e = pthread_mutex_lock(mutex); \ - if (e != 0) { \ - errno = e; \ - lsd_fatal_error(__FILE__, __LINE__, "list mutex lock"); \ - abort(); \ - } \ - } while (0) - -# define list_mutex_unlock(mutex) \ - do { \ - int e = pthread_mutex_unlock(mutex); \ - if (e != 0) { \ - errno = e; \ - lsd_fatal_error(__FILE__, __LINE__, "list mutex unlock"); \ - abort(); \ - } \ - } while (0) - -# define list_mutex_destroy(mutex) \ - do { \ - int e = pthread_mutex_destroy(mutex); \ - if (e != 0) { \ - errno = e; \ - lsd_fatal_error(__FILE__, __LINE__, "list mutex destroy"); \ - abort(); \ - } \ - } while (0) +# define list_mutex_init(mutex) \ + do { \ + int e = pthread_mutex_init(mutex, NULL); \ + if (e != 0) { \ + errno = e; \ + lsd_fatal_error(__FILE__, __LINE__, "list mutex init"); \ + abort(); \ + } \ + } while (0) + +# define list_mutex_lock(mutex) \ + do { \ + int e = pthread_mutex_lock(mutex); \ + if (e != 0) { \ + errno = e; \ + lsd_fatal_error(__FILE__, __LINE__, "list mutex lock"); \ + abort(); \ + } \ + } while (0) + +# define list_mutex_unlock(mutex) \ + do { \ + int e = pthread_mutex_unlock(mutex); \ + if (e != 0) { \ + errno = e; \ + lsd_fatal_error(__FILE__, __LINE__, "list mutex unlock"); \ + abort(); \ + } \ + } while (0) + +# define list_mutex_destroy(mutex) \ + do { \ + int e = pthread_mutex_destroy(mutex); \ + if (e != 0) { \ + errno = e; \ + lsd_fatal_error(__FILE__, __LINE__, "list mutex destroy"); \ + abort(); \ + } \ + } while (0) # ifndef NDEBUG - static int list_mutex_is_locked (pthread_mutex_t *mutex); +static int list_mutex_is_locked (pthread_mutex_t *mutex); # endif /* !NDEBUG */ #else /* !WITH_PTHREADS */ @@ -282,394 +282,307 @@ static pthread_mutex_t list_free_lock = PTHREAD_MUTEX_INITIALIZER; * Functions * ***************/ +/* list_create() + */ List list_create (ListDelF f) { - List l; - - if (!(l = list_alloc())) - return(lsd_nomem_error(__FILE__, __LINE__, "list create")); - l->head = NULL; - l->tail = &l->head; - l->iNext = NULL; - l->fDel = f; - l->count = 0; - list_mutex_init(&l->mutex); - assert(l->magic = LIST_MAGIC); /* set magic via assert abuse */ - return(l); -} + List l; + if (!(l = list_alloc())) + return(lsd_nomem_error(__FILE__, __LINE__, "list create")); + l->head = NULL; + l->tail = &l->head; + l->iNext = NULL; + l->fDel = f; + l->count = 0; + list_mutex_init(&l->mutex); + assert(l->magic = LIST_MAGIC); /* set magic via assert abuse */ + + return l; +} + +/* list_destroy() + */ 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 = ~LIST_MAGIC); /* 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 = ~LIST_MAGIC); /* clear magic via assert abuse */ - list_mutex_unlock(&l->mutex); - list_mutex_destroy(&l->mutex); - list_free(l); - return; -} + 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 = ~LIST_MAGIC); /* 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 = ~LIST_MAGIC); /* clear magic via assert abuse */ + list_mutex_unlock(&l->mutex); + list_mutex_destroy(&l->mutex); + list_free(l); +} +/* list_is_empty() + */ int list_is_empty (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 == 0); -} + 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 == 0); +} +/* list_count() + */ 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); -} + 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; +} +/* list_append() + */ void * list_append (List l, void *x) { - void *v; - - assert(l != NULL); - assert(x != NULL); - list_mutex_lock(&l->mutex); - assert(l->magic == LIST_MAGIC); - v = _list_append_locked(l, x); - list_mutex_unlock(&l->mutex); - return(v); -} + void *v; + assert(l != NULL); + assert(x != NULL); + list_mutex_lock(&l->mutex); + assert(l->magic == LIST_MAGIC); + v = _list_append_locked(l, x); + list_mutex_unlock(&l->mutex); + return v; +} + +/* list_append_list() + */ int list_append_list (List l, List sub) { - ListIterator itr; - void *v; - int n = 0; - - assert(l != NULL); - assert(l->fDel == NULL); - assert(sub != NULL); - itr = list_iterator_create(sub); - while((v = list_next(itr))) { - if (list_append(l, v)) - n++; - else - break; - } - list_iterator_destroy(itr); + ListIterator itr; + void *v; + int n = 0; + + assert(l != NULL); + assert(l->fDel == NULL); + assert(sub != NULL); + itr = list_iterator_create(sub); + while((v = list_next(itr))) { + if (list_append(l, v)) + n++; + else + break; + } + list_iterator_destroy(itr); - return n; + return n; } +/* list_transfer() + */ int list_transfer (List l, List sub) { - void *v; - int n = 0; - - assert(l != NULL); - assert(sub != NULL); - assert(l->fDel == sub->fDel); - while((v = list_pop(sub))) { - if (list_append(l, v)) - n++; - else { - if (l->fDel) - l->fDel(v); - break; + void *v; + int n = 0; + + assert(l != NULL); + assert(sub != NULL); + assert(l->fDel == sub->fDel); + while((v = list_pop(sub))) { + if (list_append(l, v)) + n++; + else { + if (l->fDel) + l->fDel(v); + break; + } } - } - return n; + return n; } +/* list_prepend() + */ void * list_prepend (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 *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; +} +/* list_find_first() + */ 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; + 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); -} + list_mutex_unlock(&l->mutex); + return v; +} +/* list_delete_all() + */ int list_delete_all (List l, ListFindF f, void *key) { - ListNode *pp; - void *v; - int n = 0; - - assert(l != NULL); - assert(f != 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; + ListNode *pp; + void *v; + int n = 0; + + assert(l != NULL); + assert(f != 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); -} + list_mutex_unlock(&l->mutex); + return n; +} +/* list_for_each() + */ 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; + 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); -} + list_mutex_unlock(&l->mutex); + return n; +} +/* list_flush() + */ int list_flush (List l) { - ListNode *pp; - void *v; - int n = 0; - - assert(l != NULL); - list_mutex_lock(&l->mutex); - assert(l->magic == LIST_MAGIC); - pp = &l->head; - while (*pp) { - if ((v = list_node_destroy(l, pp))) { - if (l->fDel) - l->fDel(v); - n++; - } - } - list_mutex_unlock(&l->mutex); - return(n); -} + ListNode *pp; + void *v; + int n = 0; -void -list_sort2 (List l, ListCmpF f) -{ - ListIterator it; - - ListNode p, q, e, tail, head; - int insize, nmerges, psize, qsize, i; - - assert(l != NULL); - assert(f != NULL); - list_mutex_lock(&l->mutex); - assert(l->magic == LIST_MAGIC); - head = l->head; - if (l->count > 1) { - insize=1; - while(1) { - p = head; - head = NULL; - tail = NULL; - - - nmerges = 0; - while(p) { - nmerges++; - q = p; - - psize=0; - for (i = 0; i < insize; i++) { - psize++; - q = q->next; - - if (!q) break; - } - qsize = insize; - while (psize > 0 || (qsize > 0 && q)) { - if (psize == 0) { - e = q; - q = q->next; - qsize--; - } else if (qsize == 0 || !q ) { - e = p; - p = p->next; - psize--; - } else if (f(p->data,q->data) <= 0) { - e = p; - p = p->next; - psize--; - } else { - e = q; - q = q->next; - qsize--; - } - if (tail) { - tail->next = e; - } else { - head = e; - } - tail = e; - } - p = q; - - } - tail->next = NULL; - if(nmerges <= 1) { - l->head = head; - l->tail = &tail->next; - for (it=l->iNext; it; it=it->iNext) { - assert(it->magic == LIST_MAGIC); - it->pos = it->list->head; - it->prev = &it->list->head; - } - - list_mutex_unlock(&l->mutex); - return; - } - insize *=2; - } - } - - list_mutex_unlock(&l->mutex); - return; -} + assert(l != NULL); + list_mutex_lock(&l->mutex); + assert(l->magic == LIST_MAGIC); -void -list_sort3 (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; + pp = &l->head; 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; - } + if ((v = list_node_destroy(l, pp))) { + if (l->fDel) + l->fDel(v); + n++; + } } - 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; + list_mutex_unlock(&l->mutex); + + return n; } +/* list_push() + */ 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 *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; } +/* list_sort() + * + * This function uses the libC qsort(). + * + */ void list_sort(List l, ListCmpF f) { @@ -723,248 +636,294 @@ list_sort(List l, ListCmpF f) list_mutex_unlock(&l->mutex); } +/* list_pop() + */ void * list_pop (List l) { - void *v; - - assert(l != NULL); - list_mutex_lock(&l->mutex); - assert(l->magic == LIST_MAGIC); - v = _list_pop_locked(l); - list_mutex_unlock(&l->mutex); - return(v); -} + void *v; + + assert(l != NULL); + list_mutex_lock(&l->mutex); + assert(l->magic == LIST_MAGIC); + v = _list_pop_locked(l); + list_mutex_unlock(&l->mutex); + return v; +} + +/* list_pop_top() + */ void * list_pop_top (List l, ListCmpF f) { - void *v = NULL; - ListNode *pp, *pTop; - assert(l != NULL); - assert(f != NULL); - list_mutex_lock(&l->mutex); - assert(l->magic == LIST_MAGIC); - pTop = &l->head; - if (*pTop) { - pp = &(*pTop)->next; - while (*pp) { - if (f(&(*pp)->data, &(*pTop)->data) > 0) - pTop = pp; - pp = &(*pp)->next; - } - v = list_node_destroy(l, pTop); - } - list_mutex_unlock(&l->mutex); - return (v); -} + void *v = NULL; + ListNode *pp, *pTop; + assert(l != NULL); + assert(f != NULL); + list_mutex_lock(&l->mutex); + assert(l->magic == LIST_MAGIC); + pTop = &l->head; + if (*pTop) { + pp = &(*pTop)->next; + while (*pp) { + if (f(&(*pp)->data, &(*pTop)->data) > 0) + pTop = pp; + pp = &(*pp)->next; + } + v = list_node_destroy(l, pTop); + } + list_mutex_unlock(&l->mutex); + + return v; +} +/* list_pop_bottom() + */ void * list_pop_bottom (List l, ListCmpF f) { - void *v = NULL; - ListNode *pp, *pBottom; - assert(l != NULL); - assert(f != NULL); - list_mutex_lock(&l->mutex); - assert(l->magic == LIST_MAGIC); - pBottom = &l->head; - if (*pBottom) { - pp = &(*pBottom)->next; - while (*pp) { - if (f(&(*pp)->data, &(*pBottom)->data) < 0) - pBottom = pp; - pp = &(*pp)->next; - } - v = list_node_destroy(l, pBottom); - } - list_mutex_unlock(&l->mutex); - return (v); + void *v = NULL; + ListNode *pp, *pBottom; + assert(l != NULL); + assert(f != NULL); + list_mutex_lock(&l->mutex); + assert(l->magic == LIST_MAGIC); + + pBottom = &l->head; + if (*pBottom) { + pp = &(*pBottom)->next; + while (*pp) { + if (f(&(*pp)->data, &(*pBottom)->data) < 0) + pBottom = pp; + pp = &(*pp)->next; + } + v = list_node_destroy(l, pBottom); + } + list_mutex_unlock(&l->mutex); + + return v; } +/* list_peek() + */ 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 *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; +} +/* list_enqueue() + */ 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 *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; +} +/* list_dequeue() + */ 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 *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; +} +/* list_iterator_create() + */ 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); -} + 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; +} + +/* list_iterator_reset() + */ 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; -} + 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); +} +/* list_iterator_destroy() + */ 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; + 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 = ~LIST_MAGIC); /* clear magic via assert abuse */ - list_iterator_free(i); - return; -} + list_mutex_unlock(&i->list->mutex); + assert(i->magic = ~LIST_MAGIC); /* clear magic via assert abuse */ + list_iterator_free(i); +} +/* list_next() + */ 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); -} + 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); +} + +/* list_insert() + */ 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 *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; +} + +/* list_find() + */ void * list_find (ListIterator i, ListFindF f, void *key) { - void *v; - - assert(i != NULL); - assert(f != NULL); - assert(key != NULL); - assert(i->magic == LIST_MAGIC); - while ((v=list_next(i)) && !f(v,key)) {;} - return(v); -} + void *v; + assert(i != NULL); + assert(f != NULL); + assert(key != NULL); + assert(i->magic == LIST_MAGIC); + while ((v = list_next(i)) && !f(v,key)) {;} + + return v; +} + +/* list_remove() + */ 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 *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; +} +/* list_delete_item() + */ int list_delete_item (ListIterator i) { - void *v; - - assert(i != NULL); - assert(i->magic == LIST_MAGIC); - if ((v = list_remove(i))) { - if (i->list->fDel) - i->list->fDel(v); - return(1); - } - return(0); -} + void *v; + assert(i != NULL); + assert(i->magic == LIST_MAGIC); + if ((v = list_remove(i))) { + if (i->list->fDel) + i->list->fDel(v); + return 1; + } + + return 0; +} + +/* list_node_create() + */ static void * list_node_create (List l, ListNode *pp, void *x) { @@ -973,114 +932,127 @@ list_node_create (List l, ListNode *pp, void *x) * Returns a ptr to data [x], or NULL if insertion fails. * This routine assumes the list is already locked upon entry. */ - ListNode p; - ListIterator i; - - assert(l != NULL); - assert(l->magic == LIST_MAGIC); - assert(list_mutex_is_locked(&l->mutex)); - assert(pp != NULL); - assert(x != NULL); - if (!(p = list_node_alloc())) - return(lsd_nomem_error(__FILE__, __LINE__, "list node create")); - p->data = x; - if (!(p->next = *pp)) - l->tail = &p->next; - *pp = p; - l->count++; - for (i=l->iNext; i; i=i->iNext) { - assert(i->magic == LIST_MAGIC); - if (i->prev == pp) - i->prev = &p->next; - else if (i->pos == p->next) - i->pos = p; - assert((i->pos == *i->prev) || (i->pos == (*i->prev)->next)); - } - return(x); -} + ListNode p; + ListIterator i; + + assert(l != NULL); + assert(l->magic == LIST_MAGIC); + assert(list_mutex_is_locked(&l->mutex)); + assert(pp != NULL); + assert(x != NULL); + + if (!(p = list_node_alloc())) + return(lsd_nomem_error(__FILE__, __LINE__, "list node create")); + + p->data = x; + if (!(p->next = *pp)) + l->tail = &p->next; + *pp = p; + l->count++; + + for (i = l->iNext; i; i = i->iNext) { + assert(i->magic == LIST_MAGIC); + if (i->prev == pp) + i->prev = &p->next; + else if (i->pos == p->next) + i->pos = p; + assert((i->pos == *i->prev) || (i->pos == (*i->prev)->next)); + } + return x; +} +/* list_node_destroy() + * + * Removes the node pointed to by [*pp] from from list [l], + * where [pp] is the address of the previous node's "next" ptr. + * Returns the data ptr associated with list item being removed, + * or NULL if [*pp] points to the NULL element. + * This routine assumes the list is already locked upon entry. + */ static void * list_node_destroy (List l, ListNode *pp) { -/* Removes the node pointed to by [*pp] from from list [l], - * where [pp] is the address of the previous node's "next" ptr. - * Returns the data ptr associated with list item being removed, - * or NULL if [*pp] points to the NULL element. - * This routine assumes the list is already locked upon entry. - */ - void *v; - ListNode p; - ListIterator i; - - assert(l != NULL); - assert(l->magic == LIST_MAGIC); - assert(list_mutex_is_locked(&l->mutex)); - assert(pp != NULL); - if (!(p = *pp)) - return(NULL); - v = p->data; - if (!(*pp = p->next)) - l->tail = pp; - l->count--; - for (i=l->iNext; i; i=i->iNext) { - assert(i->magic == LIST_MAGIC); - if (i->pos == p) - i->pos = p->next, i->prev = pp; - else if (i->prev == &p->next) - i->prev = pp; - assert((i->pos == *i->prev) || (i->pos == (*i->prev)->next)); - } - list_node_free(p); - return(v); -} + void *v; + ListNode p; + ListIterator i; + + assert(l != NULL); + assert(l->magic == LIST_MAGIC); + assert(list_mutex_is_locked(&l->mutex)); + assert(pp != NULL); + + if (!(p = *pp)) + return NULL; + + v = p->data; + if (!(*pp = p->next)) + l->tail = pp; + l->count--; + + for (i = l->iNext; i; i = i->iNext) { + assert(i->magic == LIST_MAGIC); + if (i->pos == p) + i->pos = p->next, i->prev = pp; + else if (i->prev == &p->next) + i->prev = pp; + assert((i->pos == *i->prev) || (i->pos == (*i->prev)->next)); + } + list_node_free(p); + return v; +} +/* list_alloc() + */ static List list_alloc (void) { - return(list_alloc_aux(sizeof(struct list), &list_free_lists)); + return(list_alloc_aux(sizeof(struct list), &list_free_lists)); } - +/* list_free() + */ static void list_free (List l) { - list_free_aux(l, &list_free_lists); - return; + list_free_aux(l, &list_free_lists); } - +/* list_node_alloc() + */ static ListNode list_node_alloc (void) { - return(list_alloc_aux(sizeof(struct listNode), &list_free_nodes)); + return(list_alloc_aux(sizeof(struct listNode), &list_free_nodes)); } - +/* list_node_free() + */ static void list_node_free (ListNode p) { - list_free_aux(p, &list_free_nodes); - return; + list_free_aux(p, &list_free_nodes); } - +/* list_iterator_alloc() + */ static ListIterator list_iterator_alloc (void) { - return(list_alloc_aux(sizeof(struct listIterator), &list_free_iterators)); + return(list_alloc_aux(sizeof(struct listIterator), &list_free_iterators)); } - +/* list_iterator_free() + */ static void list_iterator_free (ListIterator i) { - list_free_aux(i, &list_free_iterators); - return; + list_free_aux(i, &list_free_iterators); } - +/* list_alloc_aux() + */ static void * list_alloc_aux (int size, void *pfreelist) { @@ -1088,52 +1060,56 @@ list_alloc_aux (int size, void *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 = xmalloc(LIST_ALLOC * size))) { - px = *pfree; - plast = (void **) ((char *) *pfree + ((LIST_ALLOC - 1) * size)); - while (px < plast) - *px = (char *) px + size, px = *px; - *plast = NULL; + 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 = xmalloc(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); -} + if ((px = *pfree)) + *pfree = *px; + else + errno = ENOMEM; + list_mutex_unlock(&list_free_lock); + return px; +} +/* list_free_aux() + */ static void list_free_aux (void *x, void *pfreelist) { /* Frees the object [x], returning it to the freelist [*pfreelist]. */ #ifdef MEMORY_LEAK_DEBUG - xfree(x); + xfree(x); #else - 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); + 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); #endif - return; } #ifdef WITH_PTHREADS @@ -1150,7 +1126,6 @@ void list_install_fork_handlers (void) lsd_fatal_error(__FILE__, __LINE__, "list atfork install"); abort(); } - return; } #else void list_install_fork_handlers (void) @@ -1166,11 +1141,11 @@ list_mutex_is_locked (pthread_mutex_t *mutex) { /* Returns true if the mutex is locked; o/w, returns false. */ - int rc; + int rc; - assert(mutex != NULL); - rc = pthread_mutex_trylock(mutex); - return(rc == EBUSY ? 1 : 0); + assert(mutex != NULL); + rc = pthread_mutex_trylock(mutex); + return(rc == EBUSY ? 1 : 0); } #endif /* WITH_PTHREADS */ #endif /* !NDEBUG */ diff --git a/src/common/list.h b/src/common/list.h index 1e19fea80e9c30ddfe604b32a0667f851fcdb2e2..c12a285e5d964ad7d664047c3c454144f57ca200 100644 --- a/src/common/list.h +++ b/src/common/list.h @@ -220,16 +220,6 @@ void list_sort (List l, ListCmpF f); * This function uses the libC qsort() algorithm. */ -void list_sort2 (List l, ListCmpF f); -/* This function uses the sort merge algorithm - * Note: Sorting a list resets all iterators associated with the list. - */ - -void list_sort3 (List l, ListCmpF f); -/* This function uses the n^2 brute force algorithm. - * Note: Sorting a list resets all iterators associated with the list. - */ - /**************************** * Stack Access Functions * ****************************/