Mercurial > sdl-ios-xcode
comparison src/thread/pthread/SDL_syssem.c @ 1361:19418e4422cb
New configure-based build system. Still work in progress, but much improved
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Thu, 16 Feb 2006 10:11:48 +0000 |
parents | |
children | d910939febfa |
comparison
equal
deleted
inserted
replaced
1360:70a9cfb4cf1b | 1361:19418e4422cb |
---|---|
1 /* | |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997-2006 Sam Lantinga | |
4 | |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Lesser General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2.1 of the License, or (at your option) any later version. | |
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 | |
13 Lesser General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Lesser General Public | |
16 License along with this library; if not, write to the Free Software | |
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
18 | |
19 Sam Lantinga | |
20 slouken@libsdl.org | |
21 */ | |
22 | |
23 #include <pthread.h> | |
24 #include <semaphore.h> | |
25 | |
26 #include "SDL_thread.h" | |
27 #include "SDL_timer.h" | |
28 | |
29 /* Wrapper around POSIX 1003.1b semaphores */ | |
30 | |
31 #if MACOSX | |
32 #define USE_NAMED_SEMAPHORES 1 | |
33 #endif /* MACOSX */ | |
34 | |
35 struct SDL_semaphore { | |
36 sem_t *sem; | |
37 #if !USE_NAMED_SEMAPHORES | |
38 sem_t sem_data; | |
39 #endif | |
40 }; | |
41 | |
42 /* Create a semaphore, initialized with value */ | |
43 SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) | |
44 { | |
45 SDL_sem *sem = (SDL_sem *) SDL_malloc(sizeof(SDL_sem)); | |
46 if ( sem ) { | |
47 #if USE_NAMED_SEMAPHORES | |
48 static int semnum = 0; | |
49 char name[32]; | |
50 | |
51 SDL_snprintf(name, SDL_arraysize(name), "/SDL_sem-%d-%4.4d", getpid(), semnum++); | |
52 sem->sem = sem_open(name, O_CREAT, 0600, initial_value); | |
53 if ( sem->sem == (sem_t *)SEM_FAILED ) { | |
54 SDL_SetError("sem_open(%s) failed", name); | |
55 SDL_free(sem); | |
56 sem = NULL; | |
57 } else { | |
58 sem_unlink(name); | |
59 } | |
60 #else | |
61 if ( sem_init(&sem->sem_data, 0, initial_value) < 0 ) { | |
62 SDL_SetError("sem_init() failed"); | |
63 SDL_free(sem); | |
64 sem = NULL; | |
65 } else { | |
66 sem->sem = &sem->sem_data; | |
67 } | |
68 #endif /* USE_NAMED_SEMAPHORES */ | |
69 } else { | |
70 SDL_OutOfMemory(); | |
71 } | |
72 return sem; | |
73 } | |
74 | |
75 void SDL_DestroySemaphore(SDL_sem *sem) | |
76 { | |
77 if ( sem ) { | |
78 #if USE_NAMED_SEMAPHORES | |
79 sem_close(sem->sem); | |
80 #else | |
81 sem_destroy(sem->sem); | |
82 #endif | |
83 SDL_free(sem); | |
84 } | |
85 } | |
86 | |
87 int SDL_SemTryWait(SDL_sem *sem) | |
88 { | |
89 int retval; | |
90 | |
91 if ( ! sem ) { | |
92 SDL_SetError("Passed a NULL semaphore"); | |
93 return -1; | |
94 } | |
95 retval = SDL_MUTEX_TIMEDOUT; | |
96 if ( sem_trywait(sem->sem) == 0 ) { | |
97 retval = 0; | |
98 } | |
99 return retval; | |
100 } | |
101 | |
102 int SDL_SemWait(SDL_sem *sem) | |
103 { | |
104 int retval; | |
105 | |
106 if ( ! sem ) { | |
107 SDL_SetError("Passed a NULL semaphore"); | |
108 return -1; | |
109 } | |
110 | |
111 retval = sem_wait(sem->sem); | |
112 if ( retval < 0 ) { | |
113 SDL_SetError("sem_wait() failed"); | |
114 } | |
115 return retval; | |
116 } | |
117 | |
118 int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) | |
119 { | |
120 int retval; | |
121 | |
122 if ( ! sem ) { | |
123 SDL_SetError("Passed a NULL semaphore"); | |
124 return -1; | |
125 } | |
126 | |
127 /* Try the easy cases first */ | |
128 if ( timeout == 0 ) { | |
129 return SDL_SemTryWait(sem); | |
130 } | |
131 if ( timeout == SDL_MUTEX_MAXWAIT ) { | |
132 return SDL_SemWait(sem); | |
133 } | |
134 | |
135 /* Ack! We have to busy wait... */ | |
136 timeout += SDL_GetTicks(); | |
137 do { | |
138 retval = SDL_SemTryWait(sem); | |
139 if ( retval == 0 ) { | |
140 break; | |
141 } | |
142 SDL_Delay(1); | |
143 } while ( SDL_GetTicks() < timeout ); | |
144 | |
145 return retval; | |
146 } | |
147 | |
148 Uint32 SDL_SemValue(SDL_sem *sem) | |
149 { | |
150 int ret = 0; | |
151 if ( sem ) { | |
152 sem_getvalue(sem->sem, &ret); | |
153 if ( ret < 0 ) { | |
154 ret = 0; | |
155 } | |
156 } | |
157 return (Uint32)ret; | |
158 } | |
159 | |
160 int SDL_SemPost(SDL_sem *sem) | |
161 { | |
162 int retval; | |
163 | |
164 if ( ! sem ) { | |
165 SDL_SetError("Passed a NULL semaphore"); | |
166 return -1; | |
167 } | |
168 | |
169 retval = sem_post(sem->sem); | |
170 if ( retval < 0 ) { | |
171 SDL_SetError("sem_post() failed"); | |
172 } | |
173 return retval; | |
174 } |