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 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 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 * 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 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 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 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 * 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 * 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