/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */



#include "libuutil_common.h"

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>

#define	ELEM_TO_NODE(lp, e) \
	((uu_list_node_impl_t *)((uintptr_t)(e) + (lp)->ul_offset))

#define	NODE_TO_ELEM(lp, n) \
	((void *)((uintptr_t)(n) - (lp)->ul_offset))

/*
 * uu_list_index_ts define a location for insertion.  They are simply a
 * pointer to the object after the insertion point.  We store a mark
 * in the low-bits of the index, to help prevent mistakes.
 *
 * When debugging, the index mark changes on every insert and delete, to
 * catch stale references.
 */
#define	INDEX_MAX		(sizeof (uintptr_t) - 1)
#define	INDEX_NEXT(m)		(((m) == INDEX_MAX)? 1 : ((m) + 1) & INDEX_MAX)

#define	INDEX_TO_NODE(i)	((uu_list_node_impl_t *)((i) & ~INDEX_MAX))
#define	NODE_TO_INDEX(p, n)	(((uintptr_t)(n) & ~INDEX_MAX) | (p)->ul_index)
#define	INDEX_VALID(p, i)	(((i) & INDEX_MAX) == (p)->ul_index)
#define	INDEX_CHECK(i)		(((i) & INDEX_MAX) != 0)

#define	POOL_TO_MARKER(pp) ((void *)((uintptr_t)(pp) | 1))

static uu_list_pool_t	uu_null_lpool = { &uu_null_lpool, &uu_null_lpool };
static pthread_mutex_t	uu_lpool_list_lock = PTHREAD_MUTEX_INITIALIZER;

uu_list_pool_t *
uu_list_pool_create(const char *name, size_t objsize,
    size_t nodeoffset, uu_compare_fn_t *compare_func, uint32_t flags)
{
	uu_list_pool_t *pp, *next, *prev;

	if (name == NULL ||
	    uu_check_name(name, UU_NAME_DOMAIN) == -1 ||
	    nodeoffset + sizeof (uu_list_node_t) > objsize) {
		uu_set_error(UU_ERROR_INVALID_ARGUMENT);
		return (NULL);
	}

	if (flags & ~UU_LIST_POOL_DEBUG) {
		uu_set_error(UU_ERROR_UNKNOWN_FLAG);
		return (NULL);
	}

	pp = uu_zalloc(sizeof (uu_list_pool_t));
	if (pp == NULL) {
		uu_set_error(UU_ERROR_NO_MEMORY);
		return (NULL);
	}

	(void) strlcpy(pp->ulp_name, name, sizeof (pp->ulp_name));
	pp->ulp_nodeoffset = nodeoffset;
	pp->ulp_objsize = objsize;
	pp->ulp_cmp = compare_func;
	if (flags & UU_LIST_POOL_DEBUG)
		pp->ulp_debug = 1;
	pp->ulp_last_index = 0;

	(void) pthread_mutex_init(&pp->ulp_lock, NULL);

	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);

	(void) pthread_mutex_lock(&uu_lpool_list_lock);
	pp->ulp_next = next = &uu_null_lpool;
	pp->ulp_prev = prev = next->ulp_prev;
	next->ulp_prev = pp;
	prev->ulp_next = pp;
	(void) pthread_mutex_unlock(&uu_lpool_list_lock);

	return (pp);
}

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",
			    (int)sizeof (pp->ulp_name), pp->ulp_name,
			    (void *)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_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_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_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);
}

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_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_find(uu_list_t *lp, void *elem, void *private, uu_list_index_t *out)
{
	int sorted = lp->ul_sorted;
	uu_compare_fn_t *func = lp->ul_pool->ulp_cmp;
	uu_list_node_impl_t *np;

	if (func == NULL) {
		if (out != NULL)
			*out = 0;
		uu_set_error(UU_ERROR_NOT_SUPPORTED);
		return (NULL);
	}
	for (np = lp->ul_null_node.uln_next; np != &lp->ul_null_node;
	    np = np->uln_next) {
		void *ep = NODE_TO_ELEM(lp, np);
		int cmp = func(ep, elem, private);
		if (cmp == 0) {
			if (out != NULL)
				*out = NODE_TO_INDEX(lp, np);
			return (ep);
		}
		if (sorted && cmp > 0) {
			if (out != NULL)
				*out = NODE_TO_INDEX(lp, np);
			return (NULL);
		}
	}
	if (out != NULL)
		*out = NODE_TO_INDEX(lp, 0);
	return (NULL);
}

void *
uu_list_nearest_next(uu_list_t *lp, uu_list_index_t idx)
{
	uu_list_node_impl_t *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_nearest_next(%p, %p): %s\n",
			    (void *)lp, (void *)idx,
			    INDEX_CHECK(idx)? "outdated index" :
			    "invalid index");
		if (np->uln_prev == NULL)
			uu_panic("uu_list_nearest_next(%p, %p): out-of-date "
			    "index\n", (void *)lp, (void *)idx);
	}

	if (np == &lp->ul_null_node)
		return (NULL);
	else
		return (NODE_TO_ELEM(lp, np));
}

void *
uu_list_nearest_prev(uu_list_t *lp, uu_list_index_t idx)
{
	uu_list_node_impl_t *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_nearest_prev(%p, %p): %s\n",
			    (void *)lp, (void *)idx, INDEX_CHECK(idx)?
			    "outdated index" : "invalid index");
		if (np->uln_prev == NULL)
			uu_panic("uu_list_nearest_prev(%p, %p): out-of-date "
			    "index\n", (void *)lp, (void *)idx);
	}

	if ((np = np->uln_prev) == &lp->ul_null_node)
		return (NULL);
	else
		return (NODE_TO_ELEM(lp, np));
}

static void
list_walk_init(uu_list_walk_t *wp, uu_list_t *lp, uint32_t flags)
{
	uu_list_walk_t *next, *prev;

	int robust = (flags & UU_WALK_ROBUST);
	int direction = (flags & UU_WALK_REVERSE)? -1 : 1;

	(void) memset(wp, 0, sizeof (*wp));
	wp->ulw_list = lp;
	wp->ulw_robust = robust;
	wp->ulw_dir = direction;
	if (direction > 0)
		wp->ulw_next_result = lp->ul_null_node.uln_next;
	else
		wp->ulw_next_result = lp->ul_null_node.uln_prev;

	if (lp->ul_debug || robust) {
		/*
		 * Add this walker to the list's list of walkers so
		 * uu_list_remove() can advance us if somebody tries to
		 * remove ulw_next_result.
		 */
		wp->ulw_next = next = &lp->ul_null_walk;
		wp->ulw_prev = prev = next->ulw_prev;
		next->ulw_prev = wp;
		prev->ulw_next = wp;
	}
}

static uu_list_node_impl_t *
list_walk_advance(uu_list_walk_t *wp, uu_list_t *lp)
{
	uu_list_node_impl_t *np = wp->ulw_next_result;
	uu_list_node_impl_t *next;

	if (np == &lp->ul_null_node)
		return (NULL);

	next = (wp->ulw_dir > 0)? np->uln_next : np->uln_prev;

	wp->ulw_next_result = next;
	return (np);
}

static void
list_walk_fini(uu_list_walk_t *wp)
{
	/* GLXXX debugging? */
	if (wp->ulw_next != NULL) {
		wp->ulw_next->ulw_prev = wp->ulw_prev;
		wp->ulw_prev->ulw_next = wp->ulw_next;
		wp->ulw_next = NULL;
		wp->ulw_prev = NULL;
	}
	wp->ulw_list = NULL;
	wp->ulw_next_result = NULL;
}

uu_list_walk_t *
uu_list_walk_start(uu_list_t *lp, uint32_t flags)
{
	uu_list_walk_t *wp;

	if (flags & ~(UU_WALK_ROBUST | UU_WALK_REVERSE)) {
		uu_set_error(UU_ERROR_UNKNOWN_FLAG);
		return (NULL);
	}

	wp = uu_zalloc(sizeof (*wp));
	if (wp == NULL) {
		uu_set_error(UU_ERROR_NO_MEMORY);
		return (NULL);
	}

	list_walk_init(wp, lp, flags);
	return (wp);
}

void *
uu_list_walk_next(uu_list_walk_t *wp)
{
	uu_list_t *lp = wp->ulw_list;
	uu_list_node_impl_t *np = list_walk_advance(wp, lp);

	if (np == NULL)
		return (NULL);

	return (NODE_TO_ELEM(lp, np));
}

void
uu_list_walk_end(uu_list_walk_t *wp)
{
	list_walk_fini(wp);
	uu_free(wp);
}

int
uu_list_walk(uu_list_t *lp, uu_walk_fn_t *func, void *private, uint32_t flags)
{
	uu_list_node_impl_t *np;

	int status = UU_WALK_NEXT;

	int robust = (flags & UU_WALK_ROBUST);
	int reverse = (flags & UU_WALK_REVERSE);

	if (flags & ~(UU_WALK_ROBUST | UU_WALK_REVERSE)) {
		uu_set_error(UU_ERROR_UNKNOWN_FLAG);
		return (-1);
	}

	if (lp->ul_debug || robust) {
		uu_list_walk_t my_walk;
		void *e;

		list_walk_init(&my_walk, lp, flags);
		while (status == UU_WALK_NEXT &&
		    (e = uu_list_walk_next(&my_walk)) != NULL)
			status = (*func)(e, private);
		list_walk_fini(&my_walk);
	} else {
		if (!reverse) {
			for (np = lp->ul_null_node.uln_next;
			    status == UU_WALK_NEXT && np != &lp->ul_null_node;
			    np = np->uln_next) {
				status = (*func)(NODE_TO_ELEM(lp, np), private);
			}
		} else {
			for (np = lp->ul_null_node.uln_prev;
			    status == UU_WALK_NEXT && np != &lp->ul_null_node;
			    np = np->uln_prev) {
				status = (*func)(NODE_TO_ELEM(lp, np), private);
			}
		}
	}
	if (status >= 0)
		return (0);
	uu_set_error(UU_ERROR_CALLBACK_FAILED);
	return (-1);
}

void
uu_list_remove(uu_list_t *lp, void *elem)
{
	uu_list_node_impl_t *np = ELEM_TO_NODE(lp, elem);
	uu_list_walk_t *wp;

	if (lp->ul_debug) {
		if (np->uln_prev == NULL)
			uu_panic("uu_list_remove(%p, %p): elem not on list\n",
			    (void *)lp, elem);
		/*
		 * invalidate outstanding uu_list_index_ts.
		 */
		lp->ul_index = INDEX_NEXT(lp->ul_index);
	}

	/*
	 * robust walkers must be advanced.  In debug mode, non-robust
	 * walkers are also on the list.  If there are any, it's an error.
	 */
	for (wp = lp->ul_null_walk.ulw_next; wp != &lp->ul_null_walk;
	    wp = wp->ulw_next) {
		if (wp->ulw_robust) {
			if (np == wp->ulw_next_result)
				(void) list_walk_advance(wp, lp);
		} else if (wp->ulw_next_result != NULL) {
			uu_panic("uu_list_remove(%p, %p): active non-robust "
			    "walker\n", (void *)lp, elem);
		}
	}

	np->uln_next->uln_prev = np->uln_prev;
	np->uln_prev->uln_next = np->uln_next;

	lp->ul_numnodes--;

	np->uln_next = POOL_TO_MARKER(lp->ul_pool);
	np->uln_prev = NULL;
}

void *
uu_list_teardown(uu_list_t *lp, void **cookie)
{
	void *ep;

	/*
	 * XXX: disable list modification until list is empty
	 */
	if (lp->ul_debug && *cookie != NULL)
		uu_panic("uu_list_teardown(%p, %p): unexpected cookie\n",
		    (void *)lp, (void *)cookie);

	ep = uu_list_first(lp);
	if (ep)
		uu_list_remove(lp, ep);
	return (ep);
}

int
uu_list_insert_before(uu_list_t *lp, void *target, void *elem)
{
	uu_list_node_impl_t *np = ELEM_TO_NODE(lp, target);

	if (target == NULL)
		np = &lp->ul_null_node;

	if (lp->ul_debug) {
		if (np->uln_prev == NULL)
			uu_panic("uu_list_insert_before(%p, %p, %p): %p is "
			    "not currently on a list\n",
			    (void *)lp, target, elem, target);
	}
	if (lp->ul_sorted) {
		if (lp->ul_debug)
			uu_panic("uu_list_insert_before(%p, ...): list is "
			    "UU_LIST_SORTED\n", (void *)lp);
		uu_set_error(UU_ERROR_NOT_SUPPORTED);
		return (-1);
	}

	list_insert(lp, ELEM_TO_NODE(lp, elem), np->uln_prev, np);
	return (0);
}

int
uu_list_insert_after(uu_list_t *lp, void *target, void *elem)
{
	uu_list_node_impl_t *np = ELEM_TO_NODE(lp, target);

	if (target == NULL)
		np = &lp->ul_null_node;

	if (lp->ul_debug) {
		if (np->uln_prev == NULL)
			uu_panic("uu_list_insert_after(%p, %p, %p): %p is "
			    "not currently on a list\n",
			    (void *)lp, target, elem, target);
	}
	if (lp->ul_sorted) {
		if (lp->ul_debug)
			uu_panic("uu_list_insert_after(%p, ...): list is "
			    "UU_LIST_SORTED\n", (void *)lp);
		uu_set_error(UU_ERROR_NOT_SUPPORTED);
		return (-1);
	}

	list_insert(lp, ELEM_TO_NODE(lp, elem), np, np->uln_next);
	return (0);
}

size_t
uu_list_numnodes(uu_list_t *lp)
{
	return (lp->ul_numnodes);
}

void *
uu_list_first(uu_list_t *lp)
{
	uu_list_node_impl_t *n = lp->ul_null_node.uln_next;
	if (n == &lp->ul_null_node)
		return (NULL);
	return (NODE_TO_ELEM(lp, n));
}

void *
uu_list_last(uu_list_t *lp)
{
	uu_list_node_impl_t *n = lp->ul_null_node.uln_prev;
	if (n == &lp->ul_null_node)
		return (NULL);
	return (NODE_TO_ELEM(lp, n));
}

void *
uu_list_next(uu_list_t *lp, void *elem)
{
	uu_list_node_impl_t *n = ELEM_TO_NODE(lp, elem);

	n = n->uln_next;
	if (n == &lp->ul_null_node)
		return (NULL);
	return (NODE_TO_ELEM(lp, n));
}

void *
uu_list_prev(uu_list_t *lp, void *elem)
{
	uu_list_node_impl_t *n = ELEM_TO_NODE(lp, elem);

	n = n->uln_prev;
	if (n == &lp->ul_null_node)
		return (NULL);
	return (NODE_TO_ELEM(lp, n));
}

/*
 * called from uu_lockup() and uu_release(), as part of our fork1()-safety.
 */
void
uu_list_lockup(void)
{
	uu_list_pool_t *pp;

	(void) pthread_mutex_lock(&uu_lpool_list_lock);
	for (pp = uu_null_lpool.ulp_next; pp != &uu_null_lpool;
	    pp = pp->ulp_next)
		(void) pthread_mutex_lock(&pp->ulp_lock);
}

void
uu_list_release(void)
{
	uu_list_pool_t *pp;

	for (pp = uu_null_lpool.ulp_next; pp != &uu_null_lpool;
	    pp = pp->ulp_next)
		(void) pthread_mutex_unlock(&pp->ulp_lock);
	(void) pthread_mutex_unlock(&uu_lpool_list_lock);
}
