Mercurial > sdl-ios-xcode
annotate src/thread/bsdi/SDL_syssem.c @ 1338:604d73db6802
Removed uses of stdlib.h and string.h
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 07 Feb 2006 09:29:18 +0000 |
parents | 3692456e7b0f |
children | c71e05b4dc2e |
rev | line source |
---|---|
256 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
3 Copyright (C) 1997-2006 Sam Lantinga |
256 | 4 |
5 This library is free software; you can redistribute it and/or | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
6 modify it under the terms of the GNU Lesser General Public |
256 | 7 License as published by the Free Software Foundation; either |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
8 version 2.1 of the License, or (at your option) any later version. |
256 | 9 |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
13 Lesser General Public License for more details. |
256 | 14 |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
15 You should have received a copy of the GNU Lesser General Public |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
16 License along with this library; if not, write to the Free Software |
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
256 | 18 |
19 Sam Lantinga | |
1312
c9b51268668f
Updated copyright information and removed rcs id lines (problematic in branch merges)
Sam Lantinga <slouken@libsdl.org>
parents:
769
diff
changeset
|
20 slouken@libsdl.org |
256 | 21 */ |
22 | |
1338
604d73db6802
Removed uses of stdlib.h and string.h
Sam Lantinga <slouken@libsdl.org>
parents:
1336
diff
changeset
|
23 #include "SDL_stdlib.h" |
256 | 24 #include "SDL_error.h" |
25 #include "SDL_thread.h" | |
26 #include "SDL_timer.h" | |
27 | |
28 #ifdef SDL_USE_PTHREADS | |
29 | |
30 #include <unistd.h> /* For getpid() */ | |
31 #include <pthread.h> | |
32 | |
33 | |
34 /* | |
35 * This is semaphore.h inlined here so that BSD/OS POSIX semaphore are | |
36 * completely selfcontained without requiring any additional include files | |
37 * or libraries not present in the stock system | |
38 */ | |
39 | |
40 /* semaphore.h: POSIX 1003.1b semaphores */ | |
41 | |
42 /*- | |
43 * Copyright (c) 1996, 1997 | |
44 * HD Associates, Inc. All rights reserved. | |
45 * | |
46 * Redistribution and use in source and binary forms, with or without | |
47 * modification, are permitted provided that the following conditions | |
48 * are met: | |
49 * 1. Redistributions of source code must retain the above copyright | |
50 * notice, this list of conditions and the following disclaimer. | |
51 * 2. Redistributions in binary form must reproduce the above copyright | |
52 * notice, this list of conditions and the following disclaimer in the | |
53 * documentation and/or other materials provided with the distribution. | |
54 * 3. All advertising materials mentioning features or use of this software | |
55 * must display the following acknowledgement: | |
56 * This product includes software developed by HD Associates, Inc | |
57 * 4. Neither the name of the author nor the names of any co-contributors | |
58 * may be used to endorse or promote products derived from this software | |
59 * without specific prior written permission. | |
60 * | |
61 * THIS SOFTWARE IS PROVIDED BY HD ASSOCIATES AND CONTRIBUTORS ``AS IS'' AND | |
62 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
63 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
64 * ARE DISCLAIMED. IN NO EVENT SHALL HD ASSOCIATES OR CONTRIBUTORS BE LIABLE | |
65 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
66 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
67 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
68 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
69 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
70 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
71 * SUCH DAMAGE. | |
72 * | |
73 * $FreeBSD: src/sys/posix4/semaphore.h,v 1.6 2000/01/20 07:55:42 jasone Exp $ | |
74 */ | |
75 | |
76 #include <machine/limits.h> | |
77 | |
78 #include <sys/types.h> | |
79 #include <fcntl.h> | |
80 | |
81 /* Opaque type definition. */ | |
82 struct sem; | |
83 typedef struct sem *sem_t; | |
84 | |
85 #define SEM_FAILED ((sem_t *)0) | |
86 #define SEM_VALUE_MAX UINT_MAX | |
87 | |
88 #include <sys/cdefs.h> | |
89 | |
90 __BEGIN_DECLS | |
91 int sem_init __P((sem_t *, int, unsigned int)); | |
92 int sem_destroy __P((sem_t *)); | |
93 sem_t *sem_open __P((const char *, int, ...)); | |
94 int sem_close __P((sem_t *)); | |
95 int sem_unlink __P((const char *)); | |
96 int sem_wait __P((sem_t *)); | |
97 int sem_trywait __P((sem_t *)); | |
98 int sem_post __P((sem_t *)); | |
99 int sem_getvalue __P((sem_t *, int *)); | |
100 __END_DECLS | |
101 | |
102 /* END of inlined semaphore.h */ | |
103 | |
104 /* Wrapper around POSIX 1003.1b semaphores */ | |
105 | |
106 struct SDL_semaphore { | |
107 sem_t *sem; | |
108 sem_t sem_data; | |
109 }; | |
110 | |
111 /* Create a semaphore, initialized with value */ | |
112 SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) | |
113 { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
114 SDL_sem *sem = (SDL_sem *) SDL_malloc(sizeof(SDL_sem)); |
256 | 115 if ( sem ) { |
116 if ( sem_init(&sem->sem_data, 0, initial_value) < 0 ) { | |
117 SDL_SetError("sem_init() failed"); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
118 SDL_free(sem); |
256 | 119 sem = NULL; |
120 } else { | |
121 sem->sem = &sem->sem_data; | |
122 } | |
123 } else { | |
124 SDL_OutOfMemory(); | |
125 } | |
126 return sem; | |
127 } | |
128 | |
129 void SDL_DestroySemaphore(SDL_sem *sem) | |
130 { | |
131 if ( sem ) { | |
132 sem_destroy(sem->sem); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
133 SDL_free(sem); |
256 | 134 } |
135 } | |
136 | |
137 int SDL_SemTryWait(SDL_sem *sem) | |
138 { | |
139 int retval; | |
140 | |
141 if ( ! sem ) { | |
142 SDL_SetError("Passed a NULL semaphore"); | |
143 return -1; | |
144 } | |
145 retval = SDL_MUTEX_TIMEDOUT; | |
146 if ( sem_trywait(sem->sem) == 0 ) | |
147 retval = 0; | |
148 return retval; | |
149 } | |
150 | |
151 int SDL_SemWait(SDL_sem *sem) | |
152 { | |
153 int retval; | |
154 | |
155 if ( ! sem ) { | |
156 SDL_SetError("Passed a NULL semaphore"); | |
157 return -1; | |
158 } | |
159 | |
160 retval = sem_wait(sem->sem); | |
161 if ( retval < 0 ) { | |
162 SDL_SetError("sem_wait() failed"); | |
163 } | |
164 return retval; | |
165 } | |
166 | |
167 int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) | |
168 { | |
169 int retval; | |
170 | |
171 if ( ! sem ) { | |
172 SDL_SetError("Passed a NULL semaphore"); | |
173 return -1; | |
174 } | |
175 | |
176 /* Try the easy cases first */ | |
177 if ( timeout == 0 ) { | |
178 return SDL_SemTryWait(sem); | |
179 } | |
180 if ( timeout == SDL_MUTEX_MAXWAIT ) { | |
181 return SDL_SemWait(sem); | |
182 } | |
183 | |
184 /* Ack! We have to busy wait... */ | |
185 timeout += SDL_GetTicks(); | |
186 do { | |
187 retval = SDL_SemTryWait(sem); | |
188 if ( retval == 0 ) { | |
189 break; | |
190 } | |
191 SDL_Delay(1); | |
192 } while ( SDL_GetTicks() < timeout ); | |
193 | |
194 return retval; | |
195 } | |
196 | |
197 Uint32 SDL_SemValue(SDL_sem *sem) | |
198 { | |
199 int ret = 0; | |
200 if ( sem ) { | |
201 sem_getvalue(sem->sem, &ret); | |
202 if ( ret < 0 ) { | |
203 ret = 0; | |
204 } | |
205 } | |
206 return (Uint32)ret; | |
207 } | |
208 | |
209 int SDL_SemPost(SDL_sem *sem) | |
210 { | |
211 int retval; | |
212 | |
213 if ( ! sem ) { | |
214 SDL_SetError("Passed a NULL semaphore"); | |
215 return -1; | |
216 } | |
217 | |
218 retval = sem_post(sem->sem); | |
219 if ( retval < 0 ) { | |
220 SDL_SetError("sem_post() failed"); | |
221 } | |
222 return retval; | |
223 } | |
224 | |
225 /* | |
226 * BEGIN inlined uthread_sem.c. This is done here so that no extra libraries | |
227 * or include files not present in BSD/OS are required | |
228 */ | |
229 | |
230 /* | |
231 * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. | |
232 * All rights reserved. | |
233 * | |
234 * Redistribution and use in source and binary forms, with or without | |
235 * modification, are permitted provided that the following conditions | |
236 * are met: | |
237 * 1. Redistributions of source code must retain the above copyright | |
238 * notice(s), this list of conditions and the following disclaimer as | |
239 * the first lines of this file unmodified other than the possible | |
240 * addition of one or more copyright notices. | |
241 * 2. Redistributions in binary form must reproduce the above copyright | |
242 * notice(s), this list of conditions and the following disclaimer in | |
243 * the documentation and/or other materials provided with the | |
244 * distribution. | |
245 * | |
246 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY | |
247 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
248 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
249 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE | |
250 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
251 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
252 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | |
253 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
254 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE | |
255 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | |
256 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
257 * | |
258 * $FreeBSD: src/lib/libc_r/uthread/uthread_sem.c,v 1.3.2.1 2000/07/18 02:05:57 jasone Exp $ | |
259 */ | |
260 | |
261 #include <errno.h> | |
262 #include <pthread.h> | |
263 | |
264 /* Begin thread_private.h kluge */ | |
265 /* | |
266 * These come out of (or should go into) thread_private.h - rather than have | |
267 * to copy (or symlink) the files from the source tree these definitions are | |
268 * inlined here. Obviously these go away when this module is part of libc. | |
269 */ | |
270 struct sem { | |
271 #define SEM_MAGIC ((u_int32_t) 0x09fa4012) | |
272 u_int32_t magic; | |
273 pthread_mutex_t lock; | |
274 pthread_cond_t gtzero; | |
275 u_int32_t count; | |
276 u_int32_t nwaiters; | |
277 }; | |
278 | |
279 extern pthread_once_t _thread_init_once; | |
280 extern int _threads_initialized; | |
281 extern void _thread_init __P((void)); | |
282 #define THREAD_INIT() \ | |
283 (void) pthread_once(&_thread_init_once, _thread_init) | |
284 #define THREAD_SAFE() \ | |
285 (_threads_initialized != 0) | |
286 | |
287 #define _SEM_CHECK_VALIDITY(sem) \ | |
288 if ((*(sem))->magic != SEM_MAGIC) { \ | |
289 errno = EINVAL; \ | |
290 retval = -1; \ | |
291 goto RETURN; \ | |
292 } | |
293 /* End thread_private.h kluge */ | |
294 | |
295 int | |
296 sem_init(sem_t *sem, int pshared, unsigned int value) | |
297 { | |
298 int retval; | |
299 | |
300 if (!THREAD_SAFE()) | |
301 THREAD_INIT(); | |
302 | |
303 /* | |
304 * Range check the arguments. | |
305 */ | |
306 if (pshared != 0) { | |
307 /* | |
308 * The user wants a semaphore that can be shared among | |
309 * processes, which this implementation can't do. Sounds like a | |
310 * permissions problem to me (yeah right). | |
311 */ | |
312 errno = EPERM; | |
313 retval = -1; | |
314 goto RETURN; | |
315 } | |
316 | |
317 if (value > SEM_VALUE_MAX) { | |
318 errno = EINVAL; | |
319 retval = -1; | |
320 goto RETURN; | |
321 } | |
322 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
323 *sem = (sem_t)SDL_malloc(sizeof(struct sem)); |
256 | 324 if (*sem == NULL) { |
325 errno = ENOSPC; | |
326 retval = -1; | |
327 goto RETURN; | |
328 } | |
329 | |
330 /* | |
331 * Initialize the semaphore. | |
332 */ | |
333 if (pthread_mutex_init(&(*sem)->lock, NULL) != 0) { | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
334 SDL_free(*sem); |
256 | 335 errno = ENOSPC; |
336 retval = -1; | |
337 goto RETURN; | |
338 } | |
339 | |
340 if (pthread_cond_init(&(*sem)->gtzero, NULL) != 0) { | |
341 pthread_mutex_destroy(&(*sem)->lock); | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
342 SDL_free(*sem); |
256 | 343 errno = ENOSPC; |
344 retval = -1; | |
345 goto RETURN; | |
346 } | |
347 | |
348 (*sem)->count = (u_int32_t)value; | |
349 (*sem)->nwaiters = 0; | |
350 (*sem)->magic = SEM_MAGIC; | |
351 | |
352 retval = 0; | |
353 RETURN: | |
354 return retval; | |
355 } | |
356 | |
357 int | |
358 sem_destroy(sem_t *sem) | |
359 { | |
360 int retval; | |
361 | |
362 _SEM_CHECK_VALIDITY(sem); | |
363 | |
364 /* Make sure there are no waiters. */ | |
365 pthread_mutex_lock(&(*sem)->lock); | |
366 if ((*sem)->nwaiters > 0) { | |
367 pthread_mutex_unlock(&(*sem)->lock); | |
368 errno = EBUSY; | |
369 retval = -1; | |
370 goto RETURN; | |
371 } | |
372 pthread_mutex_unlock(&(*sem)->lock); | |
373 | |
374 pthread_mutex_destroy(&(*sem)->lock); | |
375 pthread_cond_destroy(&(*sem)->gtzero); | |
376 (*sem)->magic = 0; | |
377 | |
1336
3692456e7b0f
Use SDL_ prefixed versions of C library functions.
Sam Lantinga <slouken@libsdl.org>
parents:
1312
diff
changeset
|
378 SDL_free(*sem); |
256 | 379 |
380 retval = 0; | |
381 RETURN: | |
382 return retval; | |
383 } | |
384 | |
385 sem_t * | |
386 sem_open(const char *name, int oflag, ...) | |
387 { | |
388 errno = ENOSYS; | |
389 return SEM_FAILED; | |
390 } | |
391 | |
392 int | |
393 sem_close(sem_t *sem) | |
394 { | |
395 errno = ENOSYS; | |
396 return -1; | |
397 } | |
398 | |
399 int | |
400 sem_unlink(const char *name) | |
401 { | |
402 errno = ENOSYS; | |
403 return -1; | |
404 } | |
405 | |
406 int | |
407 sem_wait(sem_t *sem) | |
408 { | |
409 int retval; | |
410 | |
411 pthread_testcancel(); | |
412 | |
413 _SEM_CHECK_VALIDITY(sem); | |
414 | |
415 pthread_mutex_lock(&(*sem)->lock); | |
416 | |
417 while ((*sem)->count == 0) { | |
418 (*sem)->nwaiters++; | |
419 pthread_cond_wait(&(*sem)->gtzero, &(*sem)->lock); | |
420 (*sem)->nwaiters--; | |
421 } | |
422 (*sem)->count--; | |
423 | |
424 pthread_mutex_unlock(&(*sem)->lock); | |
425 | |
426 retval = 0; | |
427 RETURN: | |
428 | |
429 pthread_testcancel(); | |
430 return retval; | |
431 } | |
432 | |
433 int | |
434 sem_trywait(sem_t *sem) | |
435 { | |
436 int retval; | |
437 | |
438 _SEM_CHECK_VALIDITY(sem); | |
439 | |
440 pthread_mutex_lock(&(*sem)->lock); | |
441 | |
442 if ((*sem)->count > 0) { | |
443 (*sem)->count--; | |
444 retval = 0; | |
445 } else { | |
446 errno = EAGAIN; | |
447 retval = -1; | |
448 } | |
449 | |
450 pthread_mutex_unlock(&(*sem)->lock); | |
451 | |
452 RETURN: | |
453 return retval; | |
454 } | |
455 | |
456 int | |
457 sem_post(sem_t *sem) | |
458 { | |
459 int retval; | |
460 | |
461 _SEM_CHECK_VALIDITY(sem); | |
462 | |
463 pthread_mutex_lock(&(*sem)->lock); | |
464 | |
465 (*sem)->count++; | |
466 if ((*sem)->nwaiters > 0) { | |
467 /* | |
468 * We must use pthread_cond_broadcast() rather than | |
469 * pthread_cond_signal() in order to assure that the highest | |
470 * priority thread is run by the scheduler, since | |
471 * pthread_cond_signal() signals waiting threads in FIFO order. | |
472 */ | |
473 pthread_cond_broadcast(&(*sem)->gtzero); | |
474 } | |
475 | |
476 pthread_mutex_unlock(&(*sem)->lock); | |
477 | |
478 retval = 0; | |
479 RETURN: | |
480 return retval; | |
481 } | |
482 | |
483 int | |
484 sem_getvalue(sem_t *sem, int *sval) | |
485 { | |
486 int retval; | |
487 | |
488 _SEM_CHECK_VALIDITY(sem); | |
489 | |
490 pthread_mutex_lock(&(*sem)->lock); | |
491 *sval = (int)(*sem)->count; | |
492 pthread_mutex_unlock(&(*sem)->lock); | |
493 | |
494 retval = 0; | |
495 RETURN: | |
496 return retval; | |
497 } | |
498 | |
499 /* END of inlined uthread_sem.c */ | |
500 #endif /* SDL_USE_PTHREADS */ |