/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (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 2002 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Yet another list implementation * This is a multipurpose double-linked list. It requires that the first * two structure members of each item are the 'next' and 'prev' pointers. * This works for mblk's and other data types utilized by av1394. * * Locking is provided by the caller. */ #include #define ITEM(i) ((av1394_list_item_t *)(i)) /* * av1394_list_init() * Initializes the list */ void av1394_list_init(av1394_list_t *lp) { lp->l_head = lp->l_tail = NULL; lp->l_cnt = 0; } /* * av1394_list_head() * Returns pointer to the first item in the list (but does not remove it) */ void * av1394_list_head(av1394_list_t *lp) { return (lp->l_head); } /* * av1394_list_put_tail() * Adds item to the end of the list */ void av1394_list_put_tail(av1394_list_t *lp, void *item) { ITEM(item)->i_next = NULL; ITEM(item)->i_prev = lp->l_tail; if (lp->l_tail == NULL) { ASSERT(lp->l_head == 0); ASSERT(lp->l_cnt == 0); lp->l_head = lp->l_tail = item; } else { lp->l_tail->i_next = item; lp->l_tail = item; } lp->l_cnt++; } /* * av1394_list_put_head() * Inserts item in the front of the list */ void av1394_list_put_head(av1394_list_t *lp, void *item) { ITEM(item)->i_next = lp->l_head; ITEM(item)->i_prev = NULL; if (lp->l_head == NULL) { ASSERT(lp->l_tail == 0); ASSERT(lp->l_cnt == 0); lp->l_head = lp->l_tail = item; } else { lp->l_head->i_prev = item; lp->l_head = item; } lp->l_cnt++; } /* * av1394_list_get_head() * Removes and returns an item from the front of the list */ void * av1394_list_get_head(av1394_list_t *lp) { av1394_list_item_t *item; item = lp->l_head; if (item != NULL) { lp->l_head = item->i_next; if (item == lp->l_tail) { ASSERT(lp->l_cnt == 1); ASSERT(lp->l_head == NULL); lp->l_tail = NULL; lp->l_cnt = 0; } else { ASSERT(lp->l_cnt > 1); item->i_next->i_prev = item->i_prev; lp->l_cnt--; } item->i_next = item->i_prev = NULL; } return (item); }