1178479Sjb/*
2178479Sjb * CDDL HEADER START
3178479Sjb *
4178479Sjb * The contents of this file are subject to the terms of the
5178479Sjb * Common Development and Distribution License, Version 1.0 only
6178479Sjb * (the "License").  You may not use this file except in compliance
7178479Sjb * with the License.
8178479Sjb *
9178479Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10178479Sjb * or http://www.opensolaris.org/os/licensing.
11178479Sjb * See the License for the specific language governing permissions
12178479Sjb * and limitations under the License.
13178479Sjb *
14178479Sjb * When distributing Covered Code, include this CDDL HEADER in each
15178479Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16178479Sjb * If applicable, add the following below this CDDL HEADER, with the
17178479Sjb * fields enclosed by brackets "[]" replaced with your own identifying
18178479Sjb * information: Portions Copyright [yyyy] [name of copyright owner]
19178479Sjb *
20178479Sjb * CDDL HEADER END
21178479Sjb */
22178479Sjb/*
23178479Sjb * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24178479Sjb * Use is subject to license terms.
25178479Sjb */
26178479Sjb
27178479Sjb#pragma ident	"%Z%%M%	%I%	%E% SMI"
28178479Sjb
29178479Sjb/*
30178479Sjb * Simple doubly-linked list implementation.  This implementation assumes that
31178479Sjb * each list element contains an embedded dt_list_t (previous and next
32178479Sjb * pointers), which is typically the first member of the element struct.
33178479Sjb * An additional dt_list_t is used to store the head (dl_next) and tail
34178479Sjb * (dl_prev) pointers.  The current head and tail list elements have their
35178479Sjb * previous and next pointers set to NULL, respectively.
36178479Sjb */
37178479Sjb
38178479Sjb#include <unistd.h>
39178479Sjb#include <assert.h>
40178479Sjb#include <dt_list.h>
41178479Sjb
42178479Sjbvoid
43178479Sjbdt_list_append(dt_list_t *dlp, void *new)
44178479Sjb{
45178479Sjb	dt_list_t *p = dlp->dl_prev;	/* p = tail list element */
46178479Sjb	dt_list_t *q = new;		/* q = new list element */
47178479Sjb
48178479Sjb	dlp->dl_prev = q;
49178479Sjb	q->dl_prev = p;
50178479Sjb	q->dl_next = NULL;
51178479Sjb
52178479Sjb	if (p != NULL) {
53178479Sjb		assert(p->dl_next == NULL);
54178479Sjb		p->dl_next = q;
55178479Sjb	} else {
56178479Sjb		assert(dlp->dl_next == NULL);
57178479Sjb		dlp->dl_next = q;
58178479Sjb	}
59178479Sjb}
60178479Sjb
61178479Sjbvoid
62178479Sjbdt_list_prepend(dt_list_t *dlp, void *new)
63178479Sjb{
64178479Sjb	dt_list_t *p = new;		/* p = new list element */
65178479Sjb	dt_list_t *q = dlp->dl_next;	/* q = head list element */
66178479Sjb
67178479Sjb	dlp->dl_next = p;
68178479Sjb	p->dl_prev = NULL;
69178479Sjb	p->dl_next = q;
70178479Sjb
71178479Sjb	if (q != NULL) {
72178479Sjb		assert(q->dl_prev == NULL);
73178479Sjb		q->dl_prev = p;
74178479Sjb	} else {
75178479Sjb		assert(dlp->dl_prev == NULL);
76178479Sjb		dlp->dl_prev = p;
77178479Sjb	}
78178479Sjb}
79178479Sjb
80178479Sjbvoid
81178479Sjbdt_list_insert(dt_list_t *dlp, void *after_me, void *new)
82178479Sjb{
83178479Sjb	dt_list_t *p = after_me;
84178479Sjb	dt_list_t *q = new;
85178479Sjb
86178479Sjb	if (p == NULL || p->dl_next == NULL) {
87178479Sjb		dt_list_append(dlp, new);
88178479Sjb		return;
89178479Sjb	}
90178479Sjb
91178479Sjb	q->dl_next = p->dl_next;
92178479Sjb	q->dl_prev = p;
93178479Sjb	p->dl_next = q;
94178479Sjb	q->dl_next->dl_prev = q;
95178479Sjb}
96178479Sjb
97178479Sjbvoid
98178479Sjbdt_list_delete(dt_list_t *dlp, void *existing)
99178479Sjb{
100178479Sjb	dt_list_t *p = existing;
101178479Sjb
102178479Sjb	if (p->dl_prev != NULL)
103178479Sjb		p->dl_prev->dl_next = p->dl_next;
104178479Sjb	else
105178479Sjb		dlp->dl_next = p->dl_next;
106178479Sjb
107178479Sjb	if (p->dl_next != NULL)
108178479Sjb		p->dl_next->dl_prev = p->dl_prev;
109178479Sjb	else
110178479Sjb		dlp->dl_prev = p->dl_prev;
111178479Sjb}
112