static void list_insert(uu_list_t *lp, uu_list_node_impl_t *np, uu_list_node_impl_t *prev, uu_list_node_impl_t *next) { if (lp->ul_debug) { if (next->uln_prev != prev || prev->uln_next != next) uu_panic("insert(%p): internal error: %p and %p not " "neighbors\n", (void *)lp, (void *)next, (void *)prev); if (np->uln_next != POOL_TO_MARKER(lp->ul_pool) || np->uln_prev != NULL) { uu_panic("insert(%p): elem %p node %p corrupt, " "not initialized, or already in a list.\n", (void *)lp, NODE_TO_ELEM(lp, np), (void *)np); } /* * invalidate outstanding uu_list_index_ts. */ lp->ul_index = INDEX_NEXT(lp->ul_index); } np->uln_next = next; np->uln_prev = prev; next->uln_prev = np; prev->uln_next = np; lp->ul_numnodes++; }
uu_list_t * uu_list_create(uu_list_pool_t *pp, void *parent, uint32_t flags) { uu_list_t *lp, *next, *prev; if (flags & ~(UU_LIST_DEBUG | UU_LIST_SORTED)) { uu_set_error(UU_ERROR_UNKNOWN_FLAG); return (NULL); } if ((flags & UU_LIST_SORTED) && pp->ulp_cmp == NULL) { if (pp->ulp_debug) uu_panic("uu_list_create(%p, ...): requested " "UU_LIST_SORTED, but pool has no comparison func\n", (void *)pp); uu_set_error(UU_ERROR_NOT_SUPPORTED); return (NULL); } lp = uu_zalloc(sizeof (*lp)); if (lp == NULL) { uu_set_error(UU_ERROR_NO_MEMORY); return (NULL); } lp->ul_pool = pp; lp->ul_parent_enc = UU_PTR_ENCODE(parent); lp->ul_offset = pp->ulp_nodeoffset; lp->ul_debug = pp->ulp_debug || (flags & UU_LIST_DEBUG); lp->ul_sorted = (flags & UU_LIST_SORTED); lp->ul_numnodes = 0; lp->ul_index = (pp->ulp_last_index = INDEX_NEXT(pp->ulp_last_index)); lp->ul_null_node.uln_next = &lp->ul_null_node; lp->ul_null_node.uln_prev = &lp->ul_null_node; lp->ul_null_walk.ulw_next = &lp->ul_null_walk; lp->ul_null_walk.ulw_prev = &lp->ul_null_walk; (void) pthread_mutex_lock(&pp->ulp_lock); next = &pp->ulp_null_list; prev = UU_PTR_DECODE(next->ul_prev_enc); lp->ul_next_enc = UU_PTR_ENCODE(next); lp->ul_prev_enc = UU_PTR_ENCODE(prev); next->ul_prev_enc = UU_PTR_ENCODE(lp); prev->ul_next_enc = UU_PTR_ENCODE(lp); (void) pthread_mutex_unlock(&pp->ulp_lock); return (lp); }
uu_avl_t * uu_avl_create(uu_avl_pool_t *pp, void *parent, uint32_t flags) { uu_avl_t *ap, *next, *prev; if (flags & ~UU_AVL_DEBUG) { uu_set_error(UU_ERROR_UNKNOWN_FLAG); return (NULL); } ap = uu_zalloc(sizeof (*ap)); if (ap == NULL) { uu_set_error(UU_ERROR_NO_MEMORY); return (NULL); } ap->ua_pool = pp; ap->ua_parent_enc = UU_PTR_ENCODE(parent); ap->ua_debug = pp->uap_debug || (flags & UU_AVL_DEBUG); ap->ua_index = (pp->uap_last_index = INDEX_NEXT(pp->uap_last_index)); avl_create(&ap->ua_tree, &uu_avl_node_compare, pp->uap_objsize, pp->uap_nodeoffset); ap->ua_null_walk.uaw_next = &ap->ua_null_walk; ap->ua_null_walk.uaw_prev = &ap->ua_null_walk; (void) pthread_mutex_lock(&pp->uap_lock); next = &pp->uap_null_avl; prev = UU_PTR_DECODE(next->ua_prev_enc); ap->ua_next_enc = UU_PTR_ENCODE(next); ap->ua_prev_enc = UU_PTR_ENCODE(prev); next->ua_prev_enc = UU_PTR_ENCODE(ap); prev->ua_next_enc = UU_PTR_ENCODE(ap); (void) pthread_mutex_unlock(&pp->uap_lock); return (ap); }