1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 1999 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <sys/types.h>
28 #include <sys/param.h>
29 #include <sys/debug.h>
30 #include "ghd_queue.h"
31 
32 
33 
34 void
L1_add(L1_t * lp,L1el_t * lep,void * datap)35 L1_add(L1_t *lp, L1el_t *lep, void *datap)
36 {
37 	/* init the list element */
38 	lep->le_nextp = NULL;
39 	lep->le_datap = datap;
40 
41 	if (!lp->l1_tailp) {
42 		/* list is empty */
43 		lp->l1_headp = lep;
44 	} else {
45 		/* add it to the tailend */
46 		lp->l1_tailp->le_nextp = lep;
47 	}
48 
49 	lp->l1_tailp = lep;
50 }
51 
52 
53 /*
54  * L1Delete()
55  *
56  *	Remove a specific entry from a singly-linked list.
57  *
58  */
59 
60 void
L1_delete(L1_t * lp,L1el_t * lep)61 L1_delete(L1_t *lp, L1el_t *lep)
62 {
63 	L1el_t	*prevp;
64 
65 	if (lp->l1_headp == lep) {
66 		/* it's the first entry in the list */
67 		if ((lp->l1_headp = lep->le_nextp) == NULL) {
68 			/* the list is now empty */
69 			lp->l1_tailp = NULL;
70 		}
71 		return;
72 	}
73 
74 	for (prevp = lp->l1_headp; prevp != NULL; prevp = prevp->le_nextp) {
75 		if (prevp->le_nextp == lep) {
76 			if ((prevp->le_nextp = lep->le_nextp) == NULL)
77 				lp->l1_tailp = prevp;
78 			return;
79 		}
80 	}
81 	/* its not on this list */
82 }
83 
84 
85 /*
86  * L1_remove()
87  *
88  *	Remove the entry at the head of the list (if any).
89  *
90  */
91 
92 void *
L1_remove(L1_t * lp)93 L1_remove(L1_t *lp)
94 {
95 	L1el_t	*lep;
96 
97 	/* pop the first one off the list head */
98 	if ((lep = lp->l1_headp) == NULL) {
99 		return (NULL);
100 	}
101 
102 	/* if the list is now empty fix the tail pointer */
103 	if ((lp->l1_headp = lep->le_nextp) == NULL)
104 		lp->l1_tailp = NULL;
105 
106 	lep->le_nextp = NULL;
107 
108 	return (lep->le_datap);
109 }
110 
111 
112 void
L2_add(L2el_t * headp,L2el_t * elementp,void * private)113 L2_add(L2el_t *headp, L2el_t *elementp, void *private)
114 {
115 
116 	ASSERT(headp != NULL && elementp != NULL);
117 	ASSERT(headp->l2_nextp != NULL);
118 	ASSERT(headp->l2_prevp != NULL);
119 
120 	elementp->l2_private = private;
121 
122 	elementp->l2_nextp = headp;
123 	elementp->l2_prevp = headp->l2_prevp;
124 	headp->l2_prevp->l2_nextp = elementp;
125 	headp->l2_prevp = elementp;
126 }
127 
128 void
L2_delete(L2el_t * elementp)129 L2_delete(L2el_t *elementp)
130 {
131 
132 	ASSERT(elementp != NULL);
133 	ASSERT(elementp->l2_nextp != NULL);
134 	ASSERT(elementp->l2_prevp != NULL);
135 	ASSERT(elementp->l2_nextp->l2_prevp == elementp);
136 	ASSERT(elementp->l2_prevp->l2_nextp == elementp);
137 
138 	elementp->l2_prevp->l2_nextp = elementp->l2_nextp;
139 	elementp->l2_nextp->l2_prevp = elementp->l2_prevp;
140 
141 	/* link it to itself in case someone does a double delete */
142 	elementp->l2_nextp = elementp;
143 	elementp->l2_prevp = elementp;
144 }
145 
146 
147 void
L2_add_head(L2el_t * headp,L2el_t * elementp,void * private)148 L2_add_head(L2el_t *headp, L2el_t *elementp, void *private)
149 {
150 
151 	ASSERT(headp != NULL && elementp != NULL);
152 	ASSERT(headp->l2_nextp != NULL);
153 	ASSERT(headp->l2_prevp != NULL);
154 
155 	elementp->l2_private = private;
156 
157 	elementp->l2_prevp = headp;
158 	elementp->l2_nextp = headp->l2_nextp;
159 	headp->l2_nextp->l2_prevp = elementp;
160 	headp->l2_nextp = elementp;
161 }
162 
163 
164 
165 /*
166  * L2_remove()
167  *
168  *	Remove the entry from the head of the list (if any).
169  *
170  */
171 
172 void *
L2_remove_head(L2el_t * headp)173 L2_remove_head(L2el_t *headp)
174 {
175 	L2el_t *elementp;
176 
177 	ASSERT(headp != NULL);
178 
179 	if (L2_EMPTY(headp))
180 		return (NULL);
181 
182 	elementp = headp->l2_nextp;
183 
184 	headp->l2_nextp = elementp->l2_nextp;
185 	elementp->l2_nextp->l2_prevp = headp;
186 
187 	/* link it to itself in case someone does a double delete */
188 	elementp->l2_nextp = elementp;
189 	elementp->l2_prevp = elementp;
190 
191 	return (elementp->l2_private);
192 }
193 
194 void *
L2_next(L2el_t * elementp)195 L2_next(L2el_t *elementp)
196 {
197 
198 	ASSERT(elementp != NULL);
199 
200 	if (L2_EMPTY(elementp))
201 		return (NULL);
202 	return (elementp->l2_nextp->l2_private);
203 }
204