| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: sem.c,v 1.21 2008/11/14 15:49:20 ad Exp $ */ | | 1 | /* $NetBSD: sem.c,v 1.22 2012/03/07 23:31:44 joerg Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2003, 2006, 2007 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2003, 2006, 2007 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Jason R. Thorpe of Wasabi Systems, Inc, and by Andrew Doran. | | 8 | * by Jason R. Thorpe of Wasabi Systems, Inc, and by Andrew Doran. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -49,138 +49,112 @@ | | | @@ -49,138 +49,112 @@ |
49 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 49 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
50 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 50 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
51 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE | | 51 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE |
52 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 52 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
53 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 53 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
54 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | | 54 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
55 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | | 55 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
56 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | | 56 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
57 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | | 57 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, |
58 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 58 | * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
59 | */ | | 59 | */ |
60 | | | 60 | |
61 | #include <sys/cdefs.h> | | 61 | #include <sys/cdefs.h> |
62 | __RCSID("$NetBSD: sem.c,v 1.21 2008/11/14 15:49:20 ad Exp $"); | | 62 | __RCSID("$NetBSD: sem.c,v 1.22 2012/03/07 23:31:44 joerg Exp $"); |
63 | | | 63 | |
64 | #include <sys/types.h> | | 64 | #include <sys/types.h> |
65 | #include <sys/ksem.h> | | 65 | #include <sys/ksem.h> |
66 | #include <sys/queue.h> | | 66 | #include <sys/queue.h> |
67 | #include <stdlib.h> | | 67 | #include <stdlib.h> |
68 | #include <errno.h> | | 68 | #include <errno.h> |
69 | #include <fcntl.h> | | 69 | #include <fcntl.h> |
70 | #include <semaphore.h> | | 70 | #include <semaphore.h> |
71 | #include <stdarg.h> | | 71 | #include <stdarg.h> |
72 | | | 72 | |
73 | #include "pthread.h" | | 73 | #include "pthread.h" |
74 | #include "pthread_int.h" | | | |
75 | | | 74 | |
76 | struct _sem_st { | | 75 | struct _sem_st { |
77 | unsigned int usem_magic; | | 76 | unsigned int ksem_magic; |
78 | #define USEM_MAGIC 0x09fa4012 | | 77 | #define KSEM_MAGIC 0x90af0421U |
79 | | | 78 | |
80 | LIST_ENTRY(_sem_st) usem_list; | | 79 | LIST_ENTRY(_sem_st) ksem_list; |
81 | intptr_t usem_semid; /* 0 -> user (non-shared) */ | | 80 | intptr_t ksem_semid; /* 0 -> user (non-shared) */ |
82 | #define USEM_USER 0 /* assumes kernel does not use NULL */ | | 81 | sem_t *ksem_identity; |
83 | sem_t *usem_identity; | | | |
84 | | | | |
85 | /* Protects data below. */ | | | |
86 | pthread_mutex_t usem_interlock; | | | |
87 | pthread_cond_t usem_cv; | | | |
88 | unsigned int usem_count; | | | |
89 | }; | | 82 | }; |
90 | | | 83 | |
91 | static int sem_alloc(unsigned int value, intptr_t semid, sem_t *semp); | | 84 | static int sem_alloc(unsigned int value, intptr_t semid, sem_t *semp); |
92 | static void sem_free(sem_t sem); | | 85 | static void sem_free(sem_t sem); |
93 | | | 86 | |
94 | static LIST_HEAD(, _sem_st) named_sems = LIST_HEAD_INITIALIZER(&named_sems); | | 87 | static LIST_HEAD(, _sem_st) named_sems = LIST_HEAD_INITIALIZER(&named_sems); |
95 | static pthread_mutex_t named_sems_mtx = PTHREAD_MUTEX_INITIALIZER; | | 88 | static pthread_mutex_t named_sems_mtx = PTHREAD_MUTEX_INITIALIZER; |
96 | | | 89 | |
97 | static void | | 90 | static void |
98 | sem_free(sem_t sem) | | 91 | sem_free(sem_t sem) |
99 | { | | 92 | { |
100 | | | 93 | |
101 | if (sem->usem_semid == USEM_USER) { | | 94 | sem->ksem_magic = 0; |
102 | pthread_cond_destroy(&sem->usem_cv); | | | |
103 | pthread_mutex_destroy(&sem->usem_interlock); | | | |
104 | } | | | |
105 | sem->usem_magic = 0; | | | |
106 | free(sem); | | 95 | free(sem); |
107 | } | | 96 | } |
108 | | | 97 | |
109 | static int | | 98 | static int |
110 | sem_alloc(unsigned int value, intptr_t semid, sem_t *semp) | | 99 | sem_alloc(unsigned int value, intptr_t semid, sem_t *semp) |
111 | { | | 100 | { |
112 | sem_t sem; | | 101 | sem_t sem; |
113 | | | 102 | |
114 | if (value > SEM_VALUE_MAX) | | 103 | if (value > SEM_VALUE_MAX) |
115 | return (EINVAL); | | 104 | return (EINVAL); |
116 | | | 105 | |
117 | if ((sem = malloc(sizeof(struct _sem_st))) == NULL) | | 106 | if ((sem = malloc(sizeof(struct _sem_st))) == NULL) |
118 | return (ENOSPC); | | 107 | return (ENOSPC); |
119 | | | 108 | |
120 | sem->usem_magic = USEM_MAGIC; | | 109 | sem->ksem_magic = KSEM_MAGIC; |
121 | pthread_mutex_init(&sem->usem_interlock, NULL); | | 110 | sem->ksem_semid = semid; |
122 | pthread_cond_init(&sem->usem_cv, NULL); | | 111 | |
123 | sem->usem_count = value; | | | |
124 | sem->usem_semid = semid; | | | |
125 | | | | |
126 | *semp = sem; | | 112 | *semp = sem; |
127 | return (0); | | 113 | return (0); |
128 | } | | 114 | } |
129 | | | 115 | |
| | | 116 | /* ARGSUSED */ |
130 | int | | 117 | int |
131 | sem_init(sem_t *sem, int pshared, unsigned int value) | | 118 | sem_init(sem_t *sem, int pshared, unsigned int value) |
132 | { | | 119 | { |
133 | intptr_t semid; | | 120 | intptr_t semid; |
134 | int error; | | 121 | int error; |
135 | | | 122 | |
136 | semid = USEM_USER; | | 123 | if (_ksem_init(value, &semid) == -1) |
137 | | | | |
138 | if (pshared && _ksem_init(value, &semid) == -1) | | | |
139 | return (-1); | | 124 | return (-1); |
140 | | | 125 | |
141 | if ((error = sem_alloc(value, semid, sem)) != 0) { | | 126 | if ((error = sem_alloc(value, semid, sem)) != 0) { |
142 | if (semid != USEM_USER) | | 127 | _ksem_destroy(semid); |
143 | _ksem_destroy(semid); | | | |
144 | errno = error; | | 128 | errno = error; |
145 | return (-1); | | 129 | return (-1); |
146 | } | | 130 | } |
147 | | | 131 | |
148 | return (0); | | 132 | return (0); |
149 | } | | 133 | } |
150 | | | 134 | |
151 | int | | 135 | int |
152 | sem_destroy(sem_t *sem) | | 136 | sem_destroy(sem_t *sem) |
153 | { | | 137 | { |
154 | | | 138 | |
155 | #ifdef ERRORCHECK | | 139 | #ifdef ERRORCHECK |
156 | if (sem == NULL || *sem == NULL || (*sem)->usem_magic != USEM_MAGIC) { | | 140 | if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) { |
157 | errno = EINVAL; | | 141 | errno = EINVAL; |
158 | return (-1); | | 142 | return (-1); |
159 | } | | 143 | } |
160 | #endif | | 144 | #endif |
161 | | | 145 | |
162 | if ((*sem)->usem_semid != USEM_USER) { | | 146 | if (_ksem_destroy((*sem)->ksem_semid) == -1) |
163 | if (_ksem_destroy((*sem)->usem_semid)) | | 147 | return (-1); |
164 | return (-1); | | | |
165 | } else { | | | |
166 | pthread_mutex_lock(&(*sem)->usem_interlock); | | | |
167 | if (!PTQ_EMPTY(&(*sem)->usem_cv.ptc_waiters)) { | | | |
168 | pthread_mutex_unlock(&(*sem)->usem_interlock); | | | |
169 | errno = EBUSY; | | | |
170 | return (-1); | | | |
171 | } | | | |
172 | pthread_mutex_unlock(&(*sem)->usem_interlock); | | | |
173 | } | | | |
174 | | | 148 | |
175 | sem_free(*sem); | | 149 | sem_free(*sem); |
176 | | | 150 | |
177 | return (0); | | 151 | return (0); |
178 | } | | 152 | } |
179 | | | 153 | |
180 | sem_t * | | 154 | sem_t * |
181 | sem_open(const char *name, int oflag, ...) | | 155 | sem_open(const char *name, int oflag, ...) |
182 | { | | 156 | { |
183 | sem_t *sem, s; | | 157 | sem_t *sem, s; |
184 | intptr_t semid; | | 158 | intptr_t semid; |
185 | mode_t mode; | | 159 | mode_t mode; |
186 | unsigned int value; | | 160 | unsigned int value; |
| @@ -199,217 +173,130 @@ sem_open(const char *name, int oflag, .. | | | @@ -199,217 +173,130 @@ sem_open(const char *name, int oflag, .. |
199 | | | 173 | |
200 | /* | | 174 | /* |
201 | * We can be lazy and let the kernel handle the oflag, | | 175 | * We can be lazy and let the kernel handle the oflag, |
202 | * we'll just merge duplicate IDs into our list. | | 176 | * we'll just merge duplicate IDs into our list. |
203 | */ | | 177 | */ |
204 | if (_ksem_open(name, oflag, mode, value, &semid) == -1) | | 178 | if (_ksem_open(name, oflag, mode, value, &semid) == -1) |
205 | return (SEM_FAILED); | | 179 | return (SEM_FAILED); |
206 | | | 180 | |
207 | /* | | 181 | /* |
208 | * Search for a duplicate ID, we must return the same sem_t * | | 182 | * Search for a duplicate ID, we must return the same sem_t * |
209 | * if we locate one. | | 183 | * if we locate one. |
210 | */ | | 184 | */ |
211 | pthread_mutex_lock(&named_sems_mtx); | | 185 | pthread_mutex_lock(&named_sems_mtx); |
212 | LIST_FOREACH(s, &named_sems, usem_list) { | | 186 | LIST_FOREACH(s, &named_sems, ksem_list) { |
213 | if (s->usem_semid == semid) { | | 187 | if (s->ksem_semid == semid) { |
214 | pthread_mutex_unlock(&named_sems_mtx); | | 188 | pthread_mutex_unlock(&named_sems_mtx); |
215 | return (s->usem_identity); | | 189 | return (s->ksem_identity); |
216 | } | | 190 | } |
217 | } | | 191 | } |
218 | | | 192 | |
219 | if ((sem = malloc(sizeof(*sem))) == NULL) { | | 193 | if ((sem = malloc(sizeof(*sem))) == NULL) { |
220 | error = ENOSPC; | | 194 | error = ENOSPC; |
221 | goto bad; | | 195 | goto bad; |
222 | } | | 196 | } |
223 | if ((error = sem_alloc(value, semid, sem)) != 0) | | 197 | if ((error = sem_alloc(value, semid, sem)) != 0) |
224 | goto bad; | | 198 | goto bad; |
225 | | | 199 | |
226 | LIST_INSERT_HEAD(&named_sems, *sem, usem_list); | | 200 | LIST_INSERT_HEAD(&named_sems, *sem, ksem_list); |
227 | (*sem)->usem_identity = sem; | | | |
228 | pthread_mutex_unlock(&named_sems_mtx); | | 201 | pthread_mutex_unlock(&named_sems_mtx); |
| | | 202 | (*sem)->ksem_identity = sem; |
229 | | | 203 | |
230 | return (sem); | | 204 | return (sem); |
231 | | | 205 | |
232 | bad: | | 206 | bad: |
233 | pthread_mutex_unlock(&named_sems_mtx); | | 207 | pthread_mutex_unlock(&named_sems_mtx); |
234 | _ksem_close(semid); | | 208 | _ksem_close(semid); |
235 | if (sem != NULL) { | | 209 | if (sem != NULL) { |
236 | if (*sem != NULL) | | 210 | if (*sem != NULL) |
237 | sem_free(*sem); | | 211 | sem_free(*sem); |
238 | free(sem); | | 212 | free(sem); |
239 | } | | 213 | } |
240 | errno = error; | | 214 | errno = error; |
241 | return (SEM_FAILED); | | 215 | return (SEM_FAILED); |
242 | } | | 216 | } |
243 | | | 217 | |
244 | int | | 218 | int |
245 | sem_close(sem_t *sem) | | 219 | sem_close(sem_t *sem) |
246 | { | | 220 | { |
247 | | | 221 | |
248 | #ifdef ERRORCHECK | | 222 | #ifdef ERRORCHECK |
249 | if (sem == NULL || *sem == NULL || (*sem)->usem_magic != USEM_MAGIC) { | | 223 | if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) { |
250 | errno = EINVAL; | | 224 | errno = EINVAL; |
251 | return (-1); | | 225 | return (-1); |
252 | } | | 226 | } |
253 | #endif | | 227 | #endif |
254 | | | 228 | |
255 | if ((*sem)->usem_semid == USEM_USER) { | | | |
256 | errno = EINVAL; | | | |
257 | return (-1); | | | |
258 | } | | | |
259 | | | | |
260 | pthread_mutex_lock(&named_sems_mtx); | | 229 | pthread_mutex_lock(&named_sems_mtx); |
261 | if (_ksem_close((*sem)->usem_semid) == -1) { | | 230 | if (_ksem_close((*sem)->ksem_semid) == -1) { |
262 | pthread_mutex_unlock(&named_sems_mtx); | | 231 | pthread_mutex_unlock(&named_sems_mtx); |
263 | return (-1); | | 232 | return (-1); |
264 | } | | 233 | } |
265 | LIST_REMOVE((*sem), usem_list); | | 234 | |
| | | 235 | LIST_REMOVE((*sem), ksem_list); |
266 | pthread_mutex_unlock(&named_sems_mtx); | | 236 | pthread_mutex_unlock(&named_sems_mtx); |
267 | sem_free(*sem); | | 237 | sem_free(*sem); |
268 | free(sem); | | 238 | free(sem); |
269 | return (0); | | 239 | return (0); |
270 | } | | 240 | } |
271 | | | 241 | |
272 | int | | 242 | int |
273 | sem_unlink(const char *name) | | 243 | sem_unlink(const char *name) |
274 | { | | 244 | { |
275 | | | 245 | |
276 | return (_ksem_unlink(name)); | | 246 | return (_ksem_unlink(name)); |
277 | } | | 247 | } |
278 | | | 248 | |
279 | int | | 249 | int |
280 | sem_wait(sem_t *sem) | | 250 | sem_wait(sem_t *sem) |
281 | { | | 251 | { |
282 | pthread_t self; | | | |
283 | extern int pthread__started; | | | |
284 | | | 252 | |
285 | #ifdef ERRORCHECK | | 253 | #ifdef ERRORCHECK |
286 | if (sem == NULL || *sem == NULL || (*sem)->usem_magic != USEM_MAGIC) { | | 254 | if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) { |
287 | errno = EINVAL; | | 255 | errno = EINVAL; |
288 | return (-1); | | 256 | return (-1); |
289 | } | | 257 | } |
290 | #endif | | 258 | #endif |
291 | | | 259 | |
292 | self = pthread__self(); | | 260 | return (_ksem_wait((*sem)->ksem_semid)); |
293 | | | | |
294 | if ((*sem)->usem_semid != USEM_USER) { | | | |
295 | pthread__testcancel(self); | | | |
296 | return (_ksem_wait((*sem)->usem_semid)); | | | |
297 | } | | | |
298 | | | | |
299 | if (pthread__started == 0) { | | | |
300 | sigset_t set, oset; | | | |
301 | | | | |
302 | sigfillset(&set); | | | |
303 | (void) sigprocmask(SIG_SETMASK, &set, &oset); | | | |
304 | for (;;) { | | | |
305 | if ((*sem)->usem_count > 0) { | | | |
306 | break; | | | |
307 | } | | | |
308 | (void) sigsuspend(&oset); | | | |
309 | } | | | |
310 | (*sem)->usem_count--; | | | |
311 | (void) sigprocmask(SIG_SETMASK, &oset, NULL); | | | |
312 | return 0; | | | |
313 | } | | | |
314 | | | | |
315 | pthread_mutex_lock(&(*sem)->usem_interlock); | | | |
316 | for (;;) { | | | |
317 | if (self->pt_cancel) { | | | |
318 | pthread_mutex_unlock(&(*sem)->usem_interlock); | | | |
319 | pthread__cancelled(); | | | |
320 | } | | | |
321 | if ((*sem)->usem_count > 0) | | | |
322 | break; | | | |
323 | (void)pthread_cond_wait(&(*sem)->usem_cv, | | | |
324 | &(*sem)->usem_interlock); | | | |
325 | } | | | |
326 | (*sem)->usem_count--; | | | |
327 | pthread_mutex_unlock(&(*sem)->usem_interlock); | | | |
328 | | | | |
329 | return (0); | | | |
330 | } | | 261 | } |
331 | | | 262 | |
332 | int | | 263 | int |
333 | sem_trywait(sem_t *sem) | | 264 | sem_trywait(sem_t *sem) |
334 | { | | 265 | { |
335 | extern int pthread__started; | | | |
336 | | | 266 | |
337 | #ifdef ERRORCHECK | | 267 | #ifdef ERRORCHECK |
338 | if (sem == NULL || *sem == NULL || (*sem)->usem_magic != USEM_MAGIC) { | | 268 | if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) { |
339 | errno = EINVAL; | | 269 | errno = EINVAL; |
340 | return (-1); | | 270 | return (-1); |
341 | } | | 271 | } |
342 | #endif | | 272 | #endif |
343 | | | 273 | |
344 | if ((*sem)->usem_semid != USEM_USER) | | 274 | return (_ksem_trywait((*sem)->ksem_semid)); |
345 | return (_ksem_trywait((*sem)->usem_semid)); | | | |
346 | | | | |
347 | if (pthread__started == 0) { | | | |
348 | sigset_t set, oset; | | | |
349 | int rv = 0; | | | |
350 | | | | |
351 | sigfillset(&set); | | | |
352 | (void) sigprocmask(SIG_SETMASK, &set, &oset); | | | |
353 | if ((*sem)->usem_count > 0) { | | | |
354 | (*sem)->usem_count--; | | | |
355 | } else { | | | |
356 | errno = EAGAIN; | | | |
357 | rv = -1; | | | |
358 | } | | | |
359 | (void) sigprocmask(SIG_SETMASK, &oset, NULL); | | | |
360 | return rv; | | | |
361 | } | | | |
362 | | | | |
363 | pthread_mutex_lock(&(*sem)->usem_interlock); | | | |
364 | if ((*sem)->usem_count == 0) { | | | |
365 | pthread_mutex_unlock(&(*sem)->usem_interlock); | | | |
366 | errno = EAGAIN; | | | |
367 | return (-1); | | | |
368 | } | | | |
369 | (*sem)->usem_count--; | | | |
370 | pthread_mutex_unlock(&(*sem)->usem_interlock); | | | |
371 | | | | |
372 | return (0); | | | |
373 | } | | 275 | } |
374 | | | 276 | |
375 | int | | 277 | int |
376 | sem_post(sem_t *sem) | | 278 | sem_post(sem_t *sem) |
377 | { | | 279 | { |
378 | | | 280 | |
379 | #ifdef ERRORCHECK | | 281 | #ifdef ERRORCHECK |
380 | if (sem == NULL || *sem == NULL || (*sem)->usem_magic != USEM_MAGIC) { | | 282 | if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) { |
381 | errno = EINVAL; | | 283 | errno = EINVAL; |
382 | return (-1); | | 284 | return (-1); |
383 | } | | 285 | } |
384 | #endif | | 286 | #endif |
385 | | | 287 | |
386 | if ((*sem)->usem_semid != USEM_USER) | | 288 | return (_ksem_post((*sem)->ksem_semid)); |
387 | return (_ksem_post((*sem)->usem_semid)); | | | |
388 | | | | |
389 | pthread_mutex_lock(&(*sem)->usem_interlock); | | | |
390 | (*sem)->usem_count++; | | | |
391 | pthread_cond_signal(&(*sem)->usem_cv); | | | |
392 | pthread_mutex_unlock(&(*sem)->usem_interlock); | | | |
393 | | | | |
394 | return (0); | | | |
395 | } | | 289 | } |
396 | | | 290 | |
397 | int | | 291 | int |
398 | sem_getvalue(sem_t * __restrict sem, int * __restrict sval) | | 292 | sem_getvalue(sem_t * __restrict sem, int * __restrict sval) |
399 | { | | 293 | { |
400 | | | 294 | |
401 | #ifdef ERRORCHECK | | 295 | #ifdef ERRORCHECK |
402 | if (sem == NULL || *sem == NULL || (*sem)->usem_magic != USEM_MAGIC) { | | 296 | if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) { |
403 | errno = EINVAL; | | 297 | errno = EINVAL; |
404 | return (-1); | | 298 | return (-1); |
405 | } | | 299 | } |
406 | #endif | | 300 | #endif |
407 | if ((*sem)->usem_semid != USEM_USER) | | 301 | return (_ksem_getvalue((*sem)->ksem_semid, sval)); |
408 | return (_ksem_getvalue((*sem)->usem_semid, sval)); | | | |
409 | | | | |
410 | pthread_mutex_lock(&(*sem)->usem_interlock); | | | |
411 | *sval = (int) (*sem)->usem_count; | | | |
412 | pthread_mutex_unlock(&(*sem)->usem_interlock); | | | |
413 | | | | |
414 | return (0); | | | |
415 | } | | 302 | } |