xref: /illumos-gate/usr/src/cmd/fm/fmd/common/fmd_buf.c (revision 8d483882aa3390058094b043f3d62187b5d1de03)
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 /*
24  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 #pragma ident	"%Z%%M%	%I%	%E% SMI"
29 
30 #include <fmd_alloc.h>
31 #include <fmd_string.h>
32 #include <fmd_subr.h>
33 #include <fmd_buf.h>
34 #include <fmd.h>
35 
36 static fmd_buf_t *
37 fmd_buf_alloc(const char *name, size_t size)
38 {
39 	fmd_buf_t *bp = fmd_alloc(sizeof (fmd_buf_t), FMD_SLEEP);
40 
41 	bp->buf_name = fmd_strdup(name, FMD_SLEEP);
42 	bp->buf_next = NULL;
43 	bp->buf_data = fmd_zalloc(size, FMD_SLEEP);
44 	bp->buf_size = size;
45 	bp->buf_flags = FMD_BUF_DIRTY;
46 
47 	return (bp);
48 }
49 
50 static void
51 fmd_buf_free(fmd_buf_t *bp)
52 {
53 	fmd_strfree(bp->buf_name);
54 	fmd_free(bp->buf_data, bp->buf_size);
55 	fmd_free(bp, sizeof (fmd_buf_t));
56 }
57 
58 void
59 fmd_buf_hash_create(fmd_buf_hash_t *bhp)
60 {
61 	bhp->bh_hashlen = fmd.d_str_buckets;
62 	bhp->bh_hash = fmd_zalloc(sizeof (void *) * bhp->bh_hashlen, FMD_SLEEP);
63 	bhp->bh_count = 0;
64 }
65 
66 size_t
67 fmd_buf_hash_destroy(fmd_buf_hash_t *bhp)
68 {
69 	size_t total = 0;
70 	fmd_buf_t *bp, *np;
71 	uint_t i;
72 
73 	for (i = 0; i < bhp->bh_hashlen; i++) {
74 		for (bp = bhp->bh_hash[i]; bp != NULL; bp = np) {
75 			np = bp->buf_next;
76 			total += bp->buf_size;
77 			fmd_buf_free(bp);
78 		}
79 	}
80 
81 	fmd_free(bhp->bh_hash, sizeof (void *) * bhp->bh_hashlen);
82 	bzero(bhp, sizeof (fmd_buf_hash_t));
83 	return (total);
84 }
85 
86 void
87 fmd_buf_hash_apply(fmd_buf_hash_t *bhp, fmd_buf_f *func, void *arg)
88 {
89 	fmd_buf_t *bp;
90 	uint_t i;
91 
92 	for (i = 0; i < bhp->bh_hashlen; i++) {
93 		for (bp = bhp->bh_hash[i]; bp != NULL; bp = bp->buf_next)
94 			func(bp, arg);
95 	}
96 }
97 
98 void
99 fmd_buf_hash_commit(fmd_buf_hash_t *bhp)
100 {
101 	fmd_buf_t *bp;
102 	uint_t i;
103 
104 	for (i = 0; i < bhp->bh_hashlen; i++) {
105 		for (bp = bhp->bh_hash[i]; bp != NULL; bp = bp->buf_next)
106 			bp->buf_flags &= ~FMD_BUF_DIRTY;
107 	}
108 }
109 
110 uint_t
111 fmd_buf_hash_count(fmd_buf_hash_t *bhp)
112 {
113 	return (bhp->bh_count);
114 }
115 
116 fmd_buf_t *
117 fmd_buf_insert(fmd_buf_hash_t *bhp, const char *name, size_t size)
118 {
119 	uint_t h = fmd_strhash(name) % bhp->bh_hashlen;
120 	fmd_buf_t *bp = fmd_buf_alloc(name, size);
121 
122 	bp->buf_next = bhp->bh_hash[h];
123 	bhp->bh_hash[h] = bp;
124 	bhp->bh_count++;
125 
126 	return (bp);
127 }
128 
129 fmd_buf_t *
130 fmd_buf_lookup(fmd_buf_hash_t *bhp, const char *name)
131 {
132 	uint_t h = fmd_strhash(name) % bhp->bh_hashlen;
133 	fmd_buf_t *bp;
134 
135 	for (bp = bhp->bh_hash[h]; bp != NULL; bp = bp->buf_next) {
136 		if (strcmp(name, bp->buf_name) == 0)
137 			return (bp);
138 	}
139 
140 	return (NULL);
141 }
142 
143 void
144 fmd_buf_delete(fmd_buf_hash_t *bhp, const char *name)
145 {
146 	uint_t h = fmd_strhash(name) % bhp->bh_hashlen;
147 	fmd_buf_t *bp, **pp = &bhp->bh_hash[h];
148 
149 	for (bp = *pp; bp != NULL; bp = bp->buf_next) {
150 		if (strcmp(bp->buf_name, name) != 0)
151 			pp = &bp->buf_next;
152 		else
153 			break;
154 	}
155 
156 	if (bp != NULL) {
157 		*pp = bp->buf_next;
158 		fmd_buf_free(bp);
159 		ASSERT(bhp->bh_count != 0);
160 		bhp->bh_count--;
161 	}
162 }
163