Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5131 | clevermous | 1 | /* WARNING: This file was automatically generated! |
2 | * Original: ./src/thread/generic/SDL_syssem.c |
||
3 | */ |
||
4 | /* |
||
5 | SDL - Simple DirectMedia Layer |
||
6 | Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga |
||
7 | |||
8 | This library is free software; you can redistribute it and/or |
||
9 | modify it under the terms of the GNU Library General Public |
||
10 | License as published by the Free Software Foundation; either |
||
11 | version 2 of the License, or (at your option) any later version. |
||
12 | |||
13 | This library is distributed in the hope that it will be useful, |
||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||
16 | Library General Public License for more details. |
||
17 | |||
18 | You should have received a copy of the GNU Library General Public |
||
19 | License along with this library; if not, write to the Free |
||
20 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||
21 | |||
22 | Sam Lantinga |
||
23 | slouken@devolution.com |
||
24 | */ |
||
25 | |||
26 | |||
27 | /* An implementation of semaphores using mutexes and condition variables */ |
||
28 | |||
29 | #include |
||
30 | |||
31 | #include "SDL_error.h" |
||
32 | #include "SDL_timer.h" |
||
33 | #include "SDL_thread.h" |
||
34 | #include "SDL_systhread_c.h" |
||
35 | |||
36 | |||
37 | #ifdef DISABLE_THREADS |
||
38 | |||
39 | SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) |
||
40 | { |
||
41 | SDL_SetError("SDL not configured with thread support"); |
||
42 | return (SDL_sem *)0; |
||
43 | } |
||
44 | |||
45 | void SDL_DestroySemaphore(SDL_sem *sem) |
||
46 | { |
||
47 | return; |
||
48 | } |
||
49 | |||
50 | int SDL_SemTryWait(SDL_sem *sem) |
||
51 | { |
||
52 | SDL_SetError("SDL not configured with thread support"); |
||
53 | return -1; |
||
54 | } |
||
55 | |||
56 | int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) |
||
57 | { |
||
58 | SDL_SetError("SDL not configured with thread support"); |
||
59 | return -1; |
||
60 | } |
||
61 | |||
62 | int SDL_SemWait(SDL_sem *sem) |
||
63 | { |
||
64 | SDL_SetError("SDL not configured with thread support"); |
||
65 | return -1; |
||
66 | } |
||
67 | |||
68 | Uint32 SDL_SemValue(SDL_sem *sem) |
||
69 | { |
||
70 | return 0; |
||
71 | } |
||
72 | |||
73 | int SDL_SemPost(SDL_sem *sem) |
||
74 | { |
||
75 | SDL_SetError("SDL not configured with thread support"); |
||
76 | return -1; |
||
77 | } |
||
78 | |||
79 | #else |
||
80 | |||
81 | struct SDL_semaphore |
||
82 | { |
||
83 | Uint32 count; |
||
84 | Uint32 waiters_count; |
||
85 | SDL_mutex *count_lock; |
||
86 | SDL_cond *count_nonzero; |
||
87 | }; |
||
88 | |||
89 | SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) |
||
90 | { |
||
91 | SDL_sem *sem; |
||
92 | |||
93 | sem = (SDL_sem *)malloc(sizeof(*sem)); |
||
94 | if ( ! sem ) { |
||
95 | SDL_OutOfMemory(); |
||
96 | return(0); |
||
97 | } |
||
98 | sem->count = initial_value; |
||
99 | sem->waiters_count = 0; |
||
100 | |||
101 | sem->count_lock = SDL_CreateMutex(); |
||
102 | sem->count_nonzero = SDL_CreateCond(); |
||
103 | if ( ! sem->count_lock || ! sem->count_nonzero ) { |
||
104 | SDL_DestroySemaphore(sem); |
||
105 | return(0); |
||
106 | } |
||
107 | |||
108 | return(sem); |
||
109 | } |
||
110 | |||
111 | /* WARNING: |
||
112 | You cannot call this function when another thread is using the semaphore. |
||
113 | */ |
||
114 | void SDL_DestroySemaphore(SDL_sem *sem) |
||
115 | { |
||
116 | if ( sem ) { |
||
117 | sem->count = 0xFFFFFFFF; |
||
118 | while ( sem->waiters_count > 0) { |
||
119 | SDL_CondSignal(sem->count_nonzero); |
||
120 | SDL_Delay(10); |
||
121 | } |
||
122 | SDL_DestroyCond(sem->count_nonzero); |
||
123 | SDL_mutexP(sem->count_lock); |
||
124 | SDL_mutexV(sem->count_lock); |
||
125 | SDL_DestroyMutex(sem->count_lock); |
||
126 | free(sem); |
||
127 | } |
||
128 | } |
||
129 | |||
130 | int SDL_SemTryWait(SDL_sem *sem) |
||
131 | { |
||
132 | int retval; |
||
133 | |||
134 | if ( ! sem ) { |
||
135 | SDL_SetError("Passed a NULL semaphore"); |
||
136 | return -1; |
||
137 | } |
||
138 | |||
139 | retval = SDL_MUTEX_TIMEDOUT; |
||
140 | SDL_LockMutex(sem->count_lock); |
||
141 | if ( sem->count > 0 ) { |
||
142 | --sem->count; |
||
143 | retval = 0; |
||
144 | } |
||
145 | SDL_UnlockMutex(sem->count_lock); |
||
146 | |||
147 | return retval; |
||
148 | } |
||
149 | |||
150 | int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) |
||
151 | { |
||
152 | int retval; |
||
153 | |||
154 | if ( ! sem ) { |
||
155 | SDL_SetError("Passed a NULL semaphore"); |
||
156 | return -1; |
||
157 | } |
||
158 | |||
159 | /* A timeout of 0 is an easy case */ |
||
160 | if ( timeout == 0 ) { |
||
161 | return SDL_SemTryWait(sem); |
||
162 | } |
||
163 | |||
164 | SDL_LockMutex(sem->count_lock); |
||
165 | ++sem->waiters_count; |
||
166 | retval = 0; |
||
167 | while ( (sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT) ) { |
||
168 | retval = SDL_CondWaitTimeout(sem->count_nonzero, |
||
169 | sem->count_lock, timeout); |
||
170 | } |
||
171 | --sem->waiters_count; |
||
172 | --sem->count; |
||
173 | SDL_UnlockMutex(sem->count_lock); |
||
174 | |||
175 | return retval; |
||
176 | } |
||
177 | |||
178 | int SDL_SemWait(SDL_sem *sem) |
||
179 | { |
||
180 | return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); |
||
181 | } |
||
182 | |||
183 | Uint32 SDL_SemValue(SDL_sem *sem) |
||
184 | { |
||
185 | Uint32 value; |
||
186 | |||
187 | value = 0; |
||
188 | if ( sem ) { |
||
189 | SDL_LockMutex(sem->count_lock); |
||
190 | value = sem->count; |
||
191 | SDL_UnlockMutex(sem->count_lock); |
||
192 | } |
||
193 | return value; |
||
194 | } |
||
195 | |||
196 | int SDL_SemPost(SDL_sem *sem) |
||
197 | { |
||
198 | if ( ! sem ) { |
||
199 | SDL_SetError("Passed a NULL semaphore"); |
||
200 | return -1; |
||
201 | } |
||
202 | |||
203 | SDL_LockMutex(sem->count_lock); |
||
204 | if ( sem->waiters_count > 0 ) { |
||
205 | SDL_CondSignal(sem->count_nonzero); |
||
206 | } |
||
207 | ++sem->count; |
||
208 | SDL_UnlockMutex(sem->count_lock); |
||
209 | |||
210 | return 0; |
||
211 | } |
||
212 | |||
213 | #endif /* DISABLE_THREADS */ |