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