void uu_list_destroy(uu_list_t *lp) { uu_list_pool_t *pp = lp->ul_pool; if (lp->ul_debug) { if (lp->ul_null_node.uln_next != &lp->ul_null_node || lp->ul_null_node.uln_prev != &lp->ul_null_node) { uu_panic("uu_list_destroy(%p): list not empty\n", (void *)lp); } if (lp->ul_numnodes != 0) { uu_panic("uu_list_destroy(%p): numnodes is nonzero, " "but list is empty\n", (void *)lp); } if (lp->ul_null_walk.ulw_next != &lp->ul_null_walk || lp->ul_null_walk.ulw_prev != &lp->ul_null_walk) { uu_panic("uu_list_destroy(%p): outstanding walkers\n", (void *)lp); } } (void) pthread_mutex_lock(&pp->ulp_lock); UU_LIST_PTR(lp->ul_next_enc)->ul_prev_enc = lp->ul_prev_enc; UU_LIST_PTR(lp->ul_prev_enc)->ul_next_enc = lp->ul_next_enc; (void) pthread_mutex_unlock(&pp->ulp_lock); lp->ul_prev_enc = UU_PTR_ENCODE(NULL); lp->ul_next_enc = UU_PTR_ENCODE(NULL); lp->ul_pool = NULL; uu_free(lp); }
void uu_avl_destroy(uu_avl_t *ap) { uu_avl_pool_t *pp = ap->ua_pool; if (ap->ua_debug) { if (avl_numnodes(&ap->ua_tree) != 0) { uu_panic("uu_avl_destroy(%p): tree not empty\n", (void *)ap); } if (ap->ua_null_walk.uaw_next != &ap->ua_null_walk || ap->ua_null_walk.uaw_prev != &ap->ua_null_walk) { uu_panic("uu_avl_destroy(%p): outstanding walkers\n", (void *)ap); } } (void) pthread_mutex_lock(&pp->uap_lock); UU_AVL_PTR(ap->ua_next_enc)->ua_prev_enc = ap->ua_prev_enc; UU_AVL_PTR(ap->ua_prev_enc)->ua_next_enc = ap->ua_next_enc; (void) pthread_mutex_unlock(&pp->uap_lock); ap->ua_prev_enc = UU_PTR_ENCODE(NULL); ap->ua_next_enc = UU_PTR_ENCODE(NULL); ap->ua_pool = NULL; avl_destroy(&ap->ua_tree); uu_free(ap); }
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++; }
void uu_avl_node_fini(void *base, uu_avl_node_t *np, uu_avl_pool_t *pp) { uintptr_t *na = (uintptr_t *)np; if (pp->uap_debug) { if (na[0] == DEAD_MARKER && na[1] == DEAD_MARKER) { uu_panic("uu_avl_node_fini(%p, %p, %p (\"%s\")): " "node already finied\n", base, (void *)np, (void *)pp, pp->uap_name); } if (na[0] != POOL_TO_MARKER(pp) || na[1] != 0) { uu_panic("uu_avl_node_fini(%p, %p, %p (\"%s\")): " "node corrupt, in tree, or in different pool\n", base, (void *)np, (void *)pp, pp->uap_name); } } na[0] = DEAD_MARKER; na[1] = DEAD_MARKER; na[2] = DEAD_MARKER; }
void uu_list_insert(uu_list_t *lp, void *elem, uu_list_index_t idx) { uu_list_node_impl_t *np; np = INDEX_TO_NODE(idx); if (np == NULL) np = &lp->ul_null_node; if (lp->ul_debug) { if (!INDEX_VALID(lp, idx)) uu_panic("uu_list_insert(%p, %p, %p): %s\n", (void *)lp, elem, (void *)idx, INDEX_CHECK(idx)? "outdated index" : "invalid index"); if (np->uln_prev == NULL) uu_panic("uu_list_insert(%p, %p, %p): out-of-date " "index\n", (void *)lp, elem, (void *)idx); } list_insert(lp, ELEM_TO_NODE(lp, elem), np->uln_prev, np); }
void uu_list_node_fini(void *base, uu_list_node_t *np_arg, uu_list_pool_t *pp) { uu_list_node_impl_t *np = (uu_list_node_impl_t *)np_arg; if (pp->ulp_debug) { if (np->uln_next == NULL && np->uln_prev == NULL) { uu_panic("uu_list_node_fini(%p, %p, %p (\"%s\")): " "node already finied\n", base, (void *)np_arg, (void *)pp, pp->ulp_name); } if (np->uln_next != POOL_TO_MARKER(pp) || np->uln_prev != NULL) { uu_panic("uu_list_node_fini(%p, %p, %p (\"%s\")): " "node corrupt or on list\n", base, (void *)np_arg, (void *)pp, pp->ulp_name); } } np->uln_next = NULL; np->uln_prev = NULL; }
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); }
void uu_list_node_init(void *base, uu_list_node_t *np_arg, uu_list_pool_t *pp) { uu_list_node_impl_t *np = (uu_list_node_impl_t *)np_arg; if (pp->ulp_debug) { uintptr_t offset = (uintptr_t)np - (uintptr_t)base; if (offset + sizeof (*np) > pp->ulp_objsize) { uu_panic("uu_list_node_init(%p, %p, %p (\"%s\")): " "offset %ld doesn't fit in object (size %ld)\n", base, (void *)np, (void *)pp, pp->ulp_name, (long)offset, (long)pp->ulp_objsize); } if (offset != pp->ulp_nodeoffset) { uu_panic("uu_list_node_init(%p, %p, %p (\"%s\")): " "offset %ld doesn't match pool's offset (%ld)\n", base, (void *)np, (void *)pp, pp->ulp_name, (long)offset, (long)pp->ulp_objsize); } } np->uln_next = POOL_TO_MARKER(pp); np->uln_prev = NULL; }
void uu_avl_node_init(void *base, uu_avl_node_t *np, uu_avl_pool_t *pp) { uintptr_t *na = (uintptr_t *)np; if (pp->uap_debug) { uintptr_t offset = (uintptr_t)np - (uintptr_t)base; if (offset + sizeof (*np) > pp->uap_objsize) { uu_panic("uu_avl_node_init(%p, %p, %p (\"%s\")): " "offset %ld doesn't fit in object (size %ld)\n", base, (void *)np, (void *)pp, pp->uap_name, (long)offset, (long)pp->uap_objsize); } if (offset != pp->uap_nodeoffset) { uu_panic("uu_avl_node_init(%p, %p, %p (\"%s\")): " "offset %ld doesn't match pool's offset (%ld)\n", base, (void *)np, (void *)pp, pp->uap_name, (long)offset, (long)pp->uap_objsize); } } na[0] = POOL_TO_MARKER(pp); na[1] = 0; }
void uu_list_pool_destroy(uu_list_pool_t *pp) { if (pp->ulp_debug) { if (pp->ulp_null_list.ul_next_enc != UU_PTR_ENCODE(&pp->ulp_null_list) || pp->ulp_null_list.ul_prev_enc != UU_PTR_ENCODE(&pp->ulp_null_list)) { uu_panic("uu_list_pool_destroy: Pool \"%.*s\" (%p) has " "outstanding lists, or is corrupt.\n", sizeof (pp->ulp_name), pp->ulp_name, pp); } } (void) pthread_mutex_lock(&uu_lpool_list_lock); pp->ulp_next->ulp_prev = pp->ulp_prev; pp->ulp_prev->ulp_next = pp->ulp_next; (void) pthread_mutex_unlock(&uu_lpool_list_lock); pp->ulp_prev = NULL; pp->ulp_next = NULL; uu_free(pp); }
void uu_avl_pool_destroy(uu_avl_pool_t *pp) { if (pp->uap_debug) { if (pp->uap_null_avl.ua_next_enc != UU_PTR_ENCODE(&pp->uap_null_avl) || pp->uap_null_avl.ua_prev_enc != UU_PTR_ENCODE(&pp->uap_null_avl)) { uu_panic("uu_avl_pool_destroy: Pool \"%.*s\" (%p) has " "outstanding avls, or is corrupt.\n", (int)sizeof (pp->uap_name), pp->uap_name, (void *)pp); } } (void) pthread_mutex_lock(&uu_apool_list_lock); pp->uap_next->uap_prev = pp->uap_prev; pp->uap_prev->uap_next = pp->uap_next; (void) pthread_mutex_unlock(&uu_apool_list_lock); pp->uap_prev = NULL; pp->uap_next = NULL; uu_free(pp); }