xref: /titanic_52/usr/src/cmd/fm/fmd/common/fmd_buf.c (revision 342440ec94087b8c751c580ab9ed6c693d31d418)
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