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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1999 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #include <mdb/mdb_list.h> 28 #include <mdb/mdb_debug.h> 29 #include <unistd.h> 30 31 /* 32 * Simple doubly-linked list implementation. This implementation assumes that 33 * each list element contains an embedded mdb_list_t (previous and next 34 * pointers), which is typically the first member of the element struct. 35 * An additional mdb_list_t is used to store the head (ml_next) and tail 36 * (ml_prev) pointers. The current head and tail list elements have their 37 * previous and next pointers set to NULL, respectively. 38 */ 39 40 void 41 mdb_list_append(mdb_list_t *mlp, void *new) 42 { 43 mdb_list_t *p = mlp->ml_prev; /* p = tail list element */ 44 mdb_list_t *q = new; /* q = new list element */ 45 46 mlp->ml_prev = q; 47 q->ml_prev = p; 48 q->ml_next = NULL; 49 50 if (p != NULL) { 51 ASSERT(p->ml_next == NULL); 52 p->ml_next = q; 53 } else { 54 ASSERT(mlp->ml_next == NULL); 55 mlp->ml_next = q; 56 } 57 } 58 59 void 60 mdb_list_prepend(mdb_list_t *mlp, void *new) 61 { 62 mdb_list_t *p = new; /* p = new list element */ 63 mdb_list_t *q = mlp->ml_next; /* q = head list element */ 64 65 mlp->ml_next = p; 66 p->ml_prev = NULL; 67 p->ml_next = q; 68 69 if (q != NULL) { 70 ASSERT(q->ml_prev == NULL); 71 q->ml_prev = p; 72 } else { 73 ASSERT(mlp->ml_prev == NULL); 74 mlp->ml_prev = p; 75 } 76 } 77 78 void 79 mdb_list_insert(mdb_list_t *mlp, void *after_me, void *new) 80 { 81 mdb_list_t *p = after_me; 82 mdb_list_t *q = new; 83 84 if (p == NULL || p->ml_next == NULL) { 85 mdb_list_append(mlp, new); 86 return; 87 } 88 89 q->ml_next = p->ml_next; 90 q->ml_prev = p; 91 p->ml_next = q; 92 q->ml_next->ml_prev = q; 93 } 94 95 void 96 mdb_list_delete(mdb_list_t *mlp, void *existing) 97 { 98 mdb_list_t *p = existing; 99 100 if (p->ml_prev != NULL) 101 p->ml_prev->ml_next = p->ml_next; 102 else 103 mlp->ml_next = p->ml_next; 104 105 if (p->ml_next != NULL) 106 p->ml_next->ml_prev = p->ml_prev; 107 else 108 mlp->ml_prev = p->ml_prev; 109 } 110 111 void 112 mdb_list_move(mdb_list_t *src, mdb_list_t *dst) 113 { 114 dst->ml_prev = src->ml_prev; 115 dst->ml_next = src->ml_next; 116 src->ml_prev = NULL; 117 src->ml_next = NULL; 118 } 119