8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / rcap / rcapd / rcapd_mapping.c
blobcbb9966de49ff414d9f1fb9e79f7c58fabe17806
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <sys/types.h>
30 #include <assert.h>
31 #include <stdlib.h>
32 #include "rcapd_mapping.h"
33 #include "utils.h"
36 * lmapping_t is a list of non-overlapping mappings, ordered by address. These
37 * functions add, remove, and verify the existence of mappings in such a list.
38 * rcapd_scanner.c is a consumer.
41 typedef struct lmapping_find_cb_arg {
42 uintptr_t lmfa_addr;
43 size_t lmfa_size;
44 lmapping_t *lmfa_prior;
45 lmapping_t *lmfa_ret;
46 } lmapping_find_cb_arg_t;
48 #ifdef DEBUG
50 * Verify a sublist is properly ordered.
52 static void
53 lmapping_verify(lmapping_t *lm)
55 while (lm != NULL) {
56 if (lm->lm_next != NULL)
57 ASSERT(lm->lm_next->lm_addr > lm->lm_addr);
58 lm = lm->lm_next;
61 #else /* !DEBUG */
62 #define lmapping_verify(x) ((void)0)
63 #endif /* DEBUG */
66 * Determine the position of a mapping with the given address and size. Upon
67 * return, lmfa_ret will be set to the actual mapping, if it exists, and
68 * lmfa_prior will be set to the mapping which does or would precede one with
69 * the given characteristics.
71 static int
72 lmapping_find_cb(lmapping_t *lm, void *arg)
74 lmapping_find_cb_arg_t *lmfa = arg;
76 if (lm->lm_addr >= lmfa->lmfa_addr) {
77 if (lmfa->lmfa_addr == lm->lm_addr && lmfa->lmfa_size ==
78 lm->lm_size)
79 lmfa->lmfa_ret = lm;
80 return (1);
81 } else
82 lmfa->lmfa_prior = lm;
84 return (0);
87 static void
88 lmapping_walk(lmapping_t *lm, int(*lmapping_walk_cb)(lmapping_t *, void *),
89 void *arg)
91 lmapping_t *next;
93 while (lm != NULL) {
94 next = lm->lm_next;
95 lmapping_verify(lm);
96 if (lmapping_walk_cb(lm, arg) != 0) {
97 lmapping_verify(lm);
98 return;
100 lm = next;
105 lmapping_remove(lmapping_t **lm, uintptr_t addr, size_t size)
107 lmapping_find_cb_arg_t lmfa;
109 lmfa.lmfa_addr = addr;
110 lmfa.lmfa_size = size;
111 lmfa.lmfa_prior = lmfa.lmfa_ret = NULL;
113 lmapping_verify(*lm);
114 lmapping_walk(*lm, lmapping_find_cb, &lmfa);
115 if (lmfa.lmfa_ret == NULL)
116 return (-1);
118 if (lmfa.lmfa_prior != NULL)
119 lmfa.lmfa_prior->lm_next = lmfa.lmfa_ret->lm_next;
120 else if (*lm == lmfa.lmfa_ret)
121 *lm = lmfa.lmfa_ret->lm_next;
123 free(lmfa.lmfa_ret);
125 lmapping_verify(*lm);
127 return (0);
131 lmapping_insert(lmapping_t **lm, uintptr_t addr, size_t size)
133 lmapping_find_cb_arg_t lmfa;
134 lmapping_t *cur;
136 cur = malloc(sizeof (*cur));
137 if (cur == NULL)
138 return (-1);
140 cur->lm_addr = addr;
141 cur->lm_size = size;
142 cur->lm_next = NULL;
144 lmfa.lmfa_addr = addr;
145 lmfa.lmfa_size = size;
146 lmfa.lmfa_prior = lmfa.lmfa_ret = NULL;
148 lmapping_verify(*lm);
149 lmapping_walk(*lm, lmapping_find_cb, &lmfa);
150 ASSERT(lmfa.lmfa_ret == NULL);
151 if (lmfa.lmfa_prior != NULL) {
152 cur->lm_next = lmfa.lmfa_prior->lm_next;
153 lmfa.lmfa_prior->lm_next = cur;
154 } else {
155 cur->lm_next = *lm;
156 *lm = cur;
159 lmapping_verify(*lm);
161 return (0);
165 lmapping_contains(lmapping_t *lm, uintptr_t addr, size_t size)
167 lmapping_find_cb_arg_t lmfa;
169 lmfa.lmfa_addr = addr;
170 lmfa.lmfa_size = size;
171 lmfa.lmfa_ret = NULL;
173 lmapping_walk(lm, lmapping_find_cb, &lmfa);
174 return (lmfa.lmfa_ret != NULL);
177 /*ARGSUSED*/
178 static int
179 lmapping_free_cb(lmapping_t *lm, void *arg)
181 free(lm);
182 return (0);
185 void
186 lmapping_free(lmapping_t **lm)
188 lmapping_walk(*lm, lmapping_free_cb, NULL);
189 *lm = NULL;
192 #ifdef DEBUG
194 lmapping_dump_diff(lmapping_t *lm1, lmapping_t *lm2)
196 lmapping_t **lmv;
197 int res = 0;
198 int ch = 0;
199 int label_printed = 0;
201 #define OUTPUT_LABEL() \
202 if (label_printed == 0) { \
203 debug("changes in mappings:\n"); \
204 label_printed++; \
207 while (lm1 != NULL && lm2 != NULL) {
208 if ((lm1->lm_addr != lm2->lm_addr) || (lm1->lm_size !=
209 lm2->lm_size)) {
210 res = -1;
212 if (lm1->lm_addr == lm2->lm_addr && lm1->lm_size <
213 lm2->lm_size || lm1->lm_addr < lm2->lm_addr) {
214 lmv = &lm1;
215 ch = '-';
216 } else {
217 lmv = &lm2;
218 ch = '+';
220 OUTPUT_LABEL();
221 debug("%c%p+0x%llx\n", ch, (void *)(*lmv)->lm_addr,
222 (long long)(*lmv)->lm_size);
223 *lmv = (*lmv)->lm_next;
224 } else {
225 lm1 = lm1->lm_next;
226 lm2 = lm2->lm_next;
229 while (lm1 != NULL) {
230 OUTPUT_LABEL();
231 debug("%c%p+0x%llx\n", '-', (void *)lm1->lm_addr,
232 (unsigned long long)lm1->lm_size);
233 lm1 = lm1->lm_next;
234 res = 1;
236 while (lm2 != NULL) {
237 OUTPUT_LABEL();
238 debug("%c%p+0x%llx\n", '+', (void *)lm2->lm_addr,
239 (long long)lm2->lm_size);
240 lm2 = lm2->lm_next;
241 res = 1;
244 return (res);
245 #undef OUTPUT_LABEL
247 #endif /* DEBUG */