Print this page
5045 use atomic_{inc,dec}_* instead of atomic_add_*
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/str_conf.c
+++ new/usr/src/uts/common/io/str_conf.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License, Version 1.0 only
6 6 * (the "License"). You may not use this file except in compliance
7 7 * with the License.
8 8 *
9 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 * or http://www.opensolaris.org/os/licensing.
11 11 * See the License for the specific language governing permissions
12 12 * and limitations under the License.
13 13 *
14 14 * When distributing Covered Code, include this CDDL HEADER in each
15 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 * If applicable, add the following below this CDDL HEADER, with the
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * fields enclosed by brackets "[]" replaced with your own identifying
18 18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 19 *
20 20 * CDDL HEADER END
21 21 */
22 22 /*
23 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 -#pragma ident "%Z%%M% %I% %E% SMI"
28 -
29 27 #include <sys/types.h>
30 28 #include <sys/param.h>
31 29 #include <sys/systm.h>
32 30 #include <sys/conf.h>
33 31 #include <sys/stream.h>
34 32 #include <sys/strsubr.h>
35 33 #include <sys/modctl.h>
36 34 #include <sys/modhash.h>
37 35 #include <sys/atomic.h>
38 36
39 37 #include <sys/ddi.h>
40 38 #include <sys/sunddi.h>
41 39 #include <sys/t_lock.h>
42 40
43 41 /*
44 42 * This module provides the framework that manage STREAMS modules.
45 43 * fmodsw_alloc() is called from modconf.c as a result of a module calling
46 44 * mod_install() and fmodsw_free() is called as the result of the module
47 45 * calling mod_remove().
48 46 * fmodsw_find() will find the fmodsw_impl_t structure relating to a named
49 47 * module. There is no equivalent of driver major numbers for modules; the
50 48 * the database of fmodsw_impl_t structures is purely keyed by name and
51 49 * is hence a hash table to keep lookup cost to a minimum.
52 50 */
53 51
54 52 /*
55 53 * fmodsw_hash is the hash table that will be used to map module names to
56 54 * their fmodsw_impl_t structures. The hash function requires that the value is
57 55 * a power of 2 so this definition specifies the log of the hash table size.
58 56 */
59 57 #define FMODSW_LOG_HASHSZ 8
60 58
61 59 /*
62 60 * Hash table and associated reader-writer lock
63 61 *
64 62 * NOTE: Because the lock is global data, it is initialized to zero and hence
65 63 * a call to rw_init() is not required. Similarly all the pointers in
66 64 * the hash table will be implicitly initialized to NULL.
67 65 */
68 66 #define FMODSW_HASHSZ (1 << FMODSW_LOG_HASHSZ)
69 67
70 68 static fmodsw_impl_t *fmodsw_hash[FMODSW_HASHSZ];
71 69 static krwlock_t fmodsw_lock;
72 70
73 71 /*
74 72 * Debug code:
75 73 *
76 74 * This is not conditionally compiled since it may be useful to third
77 75 * parties when developing new modules.
78 76 */
79 77
80 78 #define BUFSZ 512
81 79
82 80 #define FMODSW_INIT 0x00000001
83 81 #define FMODSW_REGISTER 0x00000002
84 82 #define FMODSW_UNREGISTER 0x00000004
85 83 #define FMODSW_FIND 0x00000008
86 84
87 85 uint32_t fmodsw_debug_flags = 0x00000000;
88 86
89 87 static void fmodsw_dprintf(uint_t flag, const char *fmt, ...) __KPRINTFLIKE(2);
90 88
91 89 /* PRINTFLIKE2 */
92 90 static void
93 91 i_fmodsw_dprintf(uint_t flag, const char *fmt, ...)
94 92 {
95 93 va_list alist;
96 94 char buf[BUFSZ + 1];
97 95 char *ptr;
98 96
99 97 if (fmodsw_debug_flags & flag) {
100 98 va_start(alist, fmt);
101 99 ptr = buf;
102 100 (void) sprintf(ptr, "strmod debug: ");
103 101 ptr += strlen(buf);
104 102 (void) vsnprintf(ptr, buf + BUFSZ - ptr, fmt, alist);
105 103 printf(buf);
106 104 va_end(alist);
107 105 }
108 106 }
109 107
110 108
111 109 /*
112 110 * Local functions:
113 111 */
114 112
115 113 #define FMODSW_HASH(_key) \
116 114 (uint_t)(((_key[0] << 4) | (_key[1] & 0x0f)) & (FMODSW_HASHSZ - 1))
117 115
118 116 #define FMODSW_KEYCMP(_k1, _k2, _match) \
119 117 { \
120 118 char *p1 = (char *)(_k1); \
121 119 char *p2 = (char *)(_k2); \
122 120 \
123 121 while (*p1 == *p2++) { \
124 122 if (*p1++ == '\0') { \
125 123 goto _match; \
126 124 } \
127 125 } \
128 126 }
129 127
130 128 static int
131 129 i_fmodsw_hash_insert(fmodsw_impl_t *fp)
132 130 {
133 131 uint_t bucket;
134 132 fmodsw_impl_t **pp;
135 133 fmodsw_impl_t *p;
136 134
137 135 ASSERT(rw_write_held(&fmodsw_lock));
138 136
139 137 bucket = FMODSW_HASH(fp->f_name);
140 138 for (pp = &(fmodsw_hash[bucket]); (p = *pp) != NULL;
141 139 pp = &(p->f_next))
142 140 FMODSW_KEYCMP(p->f_name, fp->f_name, found);
143 141
144 142 fp->f_next = p;
145 143 *pp = fp;
146 144 return (0);
147 145
148 146 found:
149 147 return (EEXIST);
150 148 }
151 149
152 150 static int
153 151 i_fmodsw_hash_remove(const char *name, fmodsw_impl_t **fpp)
154 152 {
155 153 uint_t bucket;
156 154 fmodsw_impl_t **pp;
157 155 fmodsw_impl_t *p;
158 156
159 157 ASSERT(rw_write_held(&fmodsw_lock));
160 158
161 159 bucket = FMODSW_HASH(name);
162 160 for (pp = &(fmodsw_hash[bucket]); (p = *pp) != NULL;
163 161 pp = &(p->f_next))
164 162 FMODSW_KEYCMP(p->f_name, name, found);
165 163
166 164 return (ENOENT);
167 165
168 166 found:
169 167 if (p->f_ref > 0)
170 168 return (EBUSY);
171 169
172 170 *pp = p->f_next;
173 171 *fpp = p;
174 172 return (0);
175 173 }
176 174
177 175 static int
178 176 i_fmodsw_hash_find(const char *name, fmodsw_impl_t **fpp)
179 177 {
180 178 uint_t bucket;
181 179 fmodsw_impl_t *p;
182 180 int rc = 0;
183 181
184 182 ASSERT(rw_read_held(&fmodsw_lock));
185 183
186 184 bucket = FMODSW_HASH(name);
187 185 for (p = fmodsw_hash[bucket]; p != NULL; p = p->f_next)
188 186 FMODSW_KEYCMP(p->f_name, name, found);
189 187
190 188 rc = ENOENT;
191 189 found:
192 190 *fpp = p;
193 191 #ifdef DEBUG
194 192 if (p != NULL)
195 193 p->f_hits++;
196 194 #endif /* DEBUG */
197 195
198 196 return (rc);
199 197 }
200 198
201 199
202 200 /*
203 201 * Exported functions:
204 202 */
205 203
206 204 int
207 205 fmodsw_register(const char *name, struct streamtab *str, int flag)
208 206 {
209 207 fmodsw_impl_t *fp;
210 208 int len;
211 209 int err;
212 210 uint_t qflag;
213 211 uint_t sqtype;
214 212
215 213 if ((len = strlen(name)) > FMNAMESZ)
216 214 return (EINVAL);
217 215
218 216 if ((fp = kmem_zalloc(sizeof (fmodsw_impl_t), KM_NOSLEEP)) == NULL)
219 217 return (ENOMEM);
220 218
221 219 (void) strncpy(fp->f_name, name, len);
222 220 fp->f_name[len] = '\0';
223 221
224 222 if ((err = devflg_to_qflag(str, flag, &qflag, &sqtype)) != 0)
225 223 goto failed;
226 224
227 225 fp->f_str = str;
228 226 fp->f_qflag = qflag;
229 227 fp->f_sqtype = sqtype;
230 228 if (qflag & (QPERMOD | QMTOUTPERIM))
231 229 fp->f_dmp = hold_dm(str, qflag, sqtype);
232 230
233 231 rw_enter(&fmodsw_lock, RW_WRITER);
234 232 if ((err = i_fmodsw_hash_insert(fp)) != 0) {
235 233 rw_exit(&fmodsw_lock);
236 234 goto failed;
237 235 }
238 236 rw_exit(&fmodsw_lock);
239 237
240 238 i_fmodsw_dprintf(FMODSW_REGISTER, "registered module '%s'\n", name);
241 239 return (0);
242 240 failed:
243 241 i_fmodsw_dprintf(FMODSW_REGISTER, "failed to register module '%s'\n",
244 242 name);
245 243 if (fp->f_dmp != NULL)
246 244 rele_dm(fp->f_dmp);
247 245 kmem_free(fp, sizeof (fmodsw_impl_t));
248 246 return (err);
249 247 }
250 248
251 249 int
252 250 fmodsw_unregister(const char *name)
253 251 {
254 252 fmodsw_impl_t *fp;
255 253 int err;
256 254
257 255 rw_enter(&fmodsw_lock, RW_WRITER);
258 256 if ((err = i_fmodsw_hash_remove(name, &fp)) != 0) {
259 257 rw_exit(&fmodsw_lock);
260 258 goto failed;
261 259 }
262 260 rw_exit(&fmodsw_lock);
263 261
264 262 if (fp->f_dmp != NULL)
265 263 rele_dm(fp->f_dmp);
266 264 kmem_free(fp, sizeof (fmodsw_impl_t));
267 265
268 266 i_fmodsw_dprintf(FMODSW_UNREGISTER, "unregistered module '%s'\n",
269 267 name);
270 268 return (0);
271 269 failed:
272 270 i_fmodsw_dprintf(FMODSW_UNREGISTER, "failed to unregister module "
273 271 "'%s'\n", name);
274 272 return (err);
275 273 }
276 274
↓ open down ↓ |
238 lines elided |
↑ open up ↑ |
277 275 fmodsw_impl_t *
278 276 fmodsw_find(const char *name, fmodsw_flags_t flags)
279 277 {
280 278 fmodsw_impl_t *fp;
281 279 int id;
282 280
283 281 try_again:
284 282 rw_enter(&fmodsw_lock, RW_READER);
285 283 if (i_fmodsw_hash_find(name, &fp) == 0) {
286 284 if (flags & FMODSW_HOLD) {
287 - atomic_add_32(&(fp->f_ref), 1); /* lock must be held */
285 + atomic_inc_32(&(fp->f_ref)); /* lock must be held */
288 286 ASSERT(fp->f_ref > 0);
289 287 }
290 288
291 289 rw_exit(&fmodsw_lock);
292 290 return (fp);
293 291 }
294 292 rw_exit(&fmodsw_lock);
295 293
296 294 if (flags & FMODSW_LOAD) {
297 295 if ((id = modload("strmod", (char *)name)) != -1) {
298 296 i_fmodsw_dprintf(FMODSW_FIND,
299 297 "module '%s' loaded: id = %d\n", name, id);
300 298 goto try_again;
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
301 299 }
302 300 }
303 301
304 302 return (NULL);
305 303 }
306 304
307 305 void
308 306 fmodsw_rele(fmodsw_impl_t *fp)
309 307 {
310 308 ASSERT(fp->f_ref > 0);
311 - atomic_add_32(&(fp->f_ref), -1);
309 + atomic_dec_32(&(fp->f_ref));
312 310 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX