Mercurial > sdl-ios-xcode
comparison src/thread/nds/SDL_syscond.c @ 2671:c3e7c0698cbb gsoc2008_nds
some changes to the dummy driver for debug purposes that should be reverted.
most importantly, commenting out a check for an env. var.
author | Darren Alton <dalton@stevens.edu> |
---|---|
date | Thu, 12 Jun 2008 02:38:49 +0000 |
parents | 6e4669f4db49 |
children |
comparison
equal
deleted
inserted
replaced
2670:6e4669f4db49 | 2671:c3e7c0698cbb |
---|---|
20 slouken@devolution.com | 20 slouken@devolution.com |
21 */ | 21 */ |
22 | 22 |
23 #ifdef SAVE_RCSID | 23 #ifdef SAVE_RCSID |
24 static char rcsid = | 24 static char rcsid = |
25 "@(#) $Id: SDL_syscond.c,v 1.2 2001/04/26 16:50:18 hercules Exp $"; | 25 "@(#) $Id: SDL_syscond.c,v 1.2 2001/04/26 16:50:18 hercules Exp $"; |
26 #endif | 26 #endif |
27 | 27 |
28 /* An implementation of condition variables using semaphores and mutexes */ | 28 /* An implementation of condition variables using semaphores and mutexes */ |
29 /* | 29 /* |
30 This implementation borrows heavily from the BeOS condition variable | 30 This implementation borrows heavily from the BeOS condition variable |
37 #include "SDL_error.h" | 37 #include "SDL_error.h" |
38 #include "SDL_thread.h" | 38 #include "SDL_thread.h" |
39 | 39 |
40 struct SDL_cond | 40 struct SDL_cond |
41 { | 41 { |
42 SDL_mutex *lock; | 42 SDL_mutex *lock; |
43 int waiting; | 43 int waiting; |
44 int signals; | 44 int signals; |
45 SDL_sem *wait_sem; | 45 SDL_sem *wait_sem; |
46 SDL_sem *wait_done; | 46 SDL_sem *wait_done; |
47 }; | 47 }; |
48 | 48 |
49 /* Create a condition variable */ | 49 /* Create a condition variable */ |
50 SDL_cond * SDL_CreateCond(void) | 50 SDL_cond * |
51 { | 51 SDL_CreateCond(void) |
52 SDL_cond *cond; | 52 { |
53 | 53 SDL_cond *cond; |
54 cond = (SDL_cond *) malloc(sizeof(SDL_cond)); | 54 |
55 if ( cond ) { | 55 cond = (SDL_cond *) malloc(sizeof(SDL_cond)); |
56 cond->lock = SDL_CreateMutex(); | 56 if (cond) { |
57 cond->wait_sem = SDL_CreateSemaphore(0); | 57 cond->lock = SDL_CreateMutex(); |
58 cond->wait_done = SDL_CreateSemaphore(0); | 58 cond->wait_sem = SDL_CreateSemaphore(0); |
59 cond->waiting = cond->signals = 0; | 59 cond->wait_done = SDL_CreateSemaphore(0); |
60 if ( ! cond->lock || ! cond->wait_sem || ! cond->wait_done ) { | 60 cond->waiting = cond->signals = 0; |
61 SDL_DestroyCond(cond); | 61 if (!cond->lock || !cond->wait_sem || !cond->wait_done) { |
62 cond = NULL; | 62 SDL_DestroyCond(cond); |
63 } | 63 cond = NULL; |
64 } else { | 64 } |
65 SDL_OutOfMemory(); | 65 } else { |
66 } | 66 SDL_OutOfMemory(); |
67 return(cond); | 67 } |
68 return (cond); | |
68 } | 69 } |
69 | 70 |
70 /* Destroy a condition variable */ | 71 /* Destroy a condition variable */ |
71 void SDL_DestroyCond(SDL_cond *cond) | 72 void |
72 { | 73 SDL_DestroyCond(SDL_cond * cond) |
73 if ( cond ) { | 74 { |
74 if ( cond->wait_sem ) { | 75 if (cond) { |
75 SDL_DestroySemaphore(cond->wait_sem); | 76 if (cond->wait_sem) { |
76 } | 77 SDL_DestroySemaphore(cond->wait_sem); |
77 if ( cond->wait_done ) { | 78 } |
78 SDL_DestroySemaphore(cond->wait_done); | 79 if (cond->wait_done) { |
79 } | 80 SDL_DestroySemaphore(cond->wait_done); |
80 if ( cond->lock ) { | 81 } |
81 SDL_DestroyMutex(cond->lock); | 82 if (cond->lock) { |
82 } | 83 SDL_DestroyMutex(cond->lock); |
83 free(cond); | 84 } |
84 } | 85 free(cond); |
86 } | |
85 } | 87 } |
86 | 88 |
87 /* Restart one of the threads that are waiting on the condition variable */ | 89 /* Restart one of the threads that are waiting on the condition variable */ |
88 int SDL_CondSignal(SDL_cond *cond) | 90 int |
89 { | 91 SDL_CondSignal(SDL_cond * cond) |
90 if ( ! cond ) { | 92 { |
91 SDL_SetError("Passed a NULL condition variable"); | 93 if (!cond) { |
92 return -1; | 94 SDL_SetError("Passed a NULL condition variable"); |
93 } | 95 return -1; |
94 | 96 } |
95 /* If there are waiting threads not already signalled, then | 97 |
96 signal the condition and wait for the thread to respond. | 98 /* If there are waiting threads not already signalled, then |
97 */ | 99 signal the condition and wait for the thread to respond. |
98 SDL_LockMutex(cond->lock); | 100 */ |
99 if ( cond->waiting > cond->signals ) { | 101 SDL_LockMutex(cond->lock); |
100 ++cond->signals; | 102 if (cond->waiting > cond->signals) { |
101 SDL_SemPost(cond->wait_sem); | 103 ++cond->signals; |
102 SDL_UnlockMutex(cond->lock); | 104 SDL_SemPost(cond->wait_sem); |
103 SDL_SemWait(cond->wait_done); | 105 SDL_UnlockMutex(cond->lock); |
104 } else { | 106 SDL_SemWait(cond->wait_done); |
105 SDL_UnlockMutex(cond->lock); | 107 } else { |
106 } | 108 SDL_UnlockMutex(cond->lock); |
107 | 109 } |
108 return 0; | 110 |
111 return 0; | |
109 } | 112 } |
110 | 113 |
111 /* Restart all threads that are waiting on the condition variable */ | 114 /* Restart all threads that are waiting on the condition variable */ |
112 int SDL_CondBroadcast(SDL_cond *cond) | 115 int |
113 { | 116 SDL_CondBroadcast(SDL_cond * cond) |
114 if ( ! cond ) { | 117 { |
115 SDL_SetError("Passed a NULL condition variable"); | 118 if (!cond) { |
116 return -1; | 119 SDL_SetError("Passed a NULL condition variable"); |
117 } | 120 return -1; |
118 | 121 } |
119 /* If there are waiting threads not already signalled, then | 122 |
120 signal the condition and wait for the thread to respond. | 123 /* If there are waiting threads not already signalled, then |
121 */ | 124 signal the condition and wait for the thread to respond. |
122 SDL_LockMutex(cond->lock); | 125 */ |
123 if ( cond->waiting > cond->signals ) { | 126 SDL_LockMutex(cond->lock); |
124 int i, num_waiting; | 127 if (cond->waiting > cond->signals) { |
125 | 128 int i, num_waiting; |
126 num_waiting = (cond->waiting - cond->signals); | 129 |
127 cond->signals = cond->waiting; | 130 num_waiting = (cond->waiting - cond->signals); |
128 for ( i=0; i<num_waiting; ++i ) { | 131 cond->signals = cond->waiting; |
129 SDL_SemPost(cond->wait_sem); | 132 for (i = 0; i < num_waiting; ++i) { |
130 } | 133 SDL_SemPost(cond->wait_sem); |
131 /* Now all released threads are blocked here, waiting for us. | 134 } |
132 Collect them all (and win fabulous prizes!) :-) | 135 /* Now all released threads are blocked here, waiting for us. |
133 */ | 136 Collect them all (and win fabulous prizes!) :-) |
134 SDL_UnlockMutex(cond->lock); | 137 */ |
135 for ( i=0; i<num_waiting; ++i ) { | 138 SDL_UnlockMutex(cond->lock); |
136 SDL_SemWait(cond->wait_done); | 139 for (i = 0; i < num_waiting; ++i) { |
137 } | 140 SDL_SemWait(cond->wait_done); |
138 } else { | 141 } |
139 SDL_UnlockMutex(cond->lock); | 142 } else { |
140 } | 143 SDL_UnlockMutex(cond->lock); |
141 | 144 } |
142 return 0; | 145 |
146 return 0; | |
143 } | 147 } |
144 | 148 |
145 /* Wait on the condition variable for at most 'ms' milliseconds. | 149 /* Wait on the condition variable for at most 'ms' milliseconds. |
146 The mutex must be locked before entering this function! | 150 The mutex must be locked before entering this function! |
147 The mutex is unlocked during the wait, and locked again after the wait. | 151 The mutex is unlocked during the wait, and locked again after the wait. |
160 ... | 164 ... |
161 condition = true; | 165 condition = true; |
162 ... | 166 ... |
163 SDL_UnlockMutex(lock); | 167 SDL_UnlockMutex(lock); |
164 */ | 168 */ |
165 int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms) | 169 int |
166 { | 170 SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms) |
167 int retval; | 171 { |
168 | 172 int retval; |
169 if ( ! cond ) { | 173 |
170 SDL_SetError("Passed a NULL condition variable"); | 174 if (!cond) { |
171 return -1; | 175 SDL_SetError("Passed a NULL condition variable"); |
172 } | 176 return -1; |
173 | 177 } |
174 /* Obtain the protection mutex, and increment the number of waiters. | 178 |
175 This allows the signal mechanism to only perform a signal if there | 179 /* Obtain the protection mutex, and increment the number of waiters. |
176 are waiting threads. | 180 This allows the signal mechanism to only perform a signal if there |
177 */ | 181 are waiting threads. |
178 SDL_LockMutex(cond->lock); | 182 */ |
179 ++cond->waiting; | 183 SDL_LockMutex(cond->lock); |
180 SDL_UnlockMutex(cond->lock); | 184 ++cond->waiting; |
181 | 185 SDL_UnlockMutex(cond->lock); |
182 /* Unlock the mutex, as is required by condition variable semantics */ | 186 |
183 SDL_UnlockMutex(mutex); | 187 /* Unlock the mutex, as is required by condition variable semantics */ |
184 | 188 SDL_UnlockMutex(mutex); |
185 /* Wait for a signal */ | 189 |
186 if ( ms == SDL_MUTEX_MAXWAIT ) { | 190 /* Wait for a signal */ |
187 retval = SDL_SemWait(cond->wait_sem); | 191 if (ms == SDL_MUTEX_MAXWAIT) { |
188 } else { | 192 retval = SDL_SemWait(cond->wait_sem); |
189 retval = SDL_SemWaitTimeout(cond->wait_sem, ms); | 193 } else { |
190 } | 194 retval = SDL_SemWaitTimeout(cond->wait_sem, ms); |
191 | 195 } |
192 /* Let the signaler know we have completed the wait, otherwise | 196 |
193 the signaler can race ahead and get the condition semaphore | 197 /* Let the signaler know we have completed the wait, otherwise |
194 if we are stopped between the mutex unlock and semaphore wait, | 198 the signaler can race ahead and get the condition semaphore |
195 giving a deadlock. See the following URL for details: | 199 if we are stopped between the mutex unlock and semaphore wait, |
196 http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html | 200 giving a deadlock. See the following URL for details: |
197 */ | 201 http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html |
198 SDL_LockMutex(cond->lock); | 202 */ |
199 if ( cond->signals > 0 ) { | 203 SDL_LockMutex(cond->lock); |
200 /* If we timed out, we need to eat a condition signal */ | 204 if (cond->signals > 0) { |
201 if ( retval > 0 ) { | 205 /* If we timed out, we need to eat a condition signal */ |
202 SDL_SemWait(cond->wait_sem); | 206 if (retval > 0) { |
203 } | 207 SDL_SemWait(cond->wait_sem); |
204 /* We always notify the signal thread that we are done */ | 208 } |
205 SDL_SemPost(cond->wait_done); | 209 /* We always notify the signal thread that we are done */ |
206 | 210 SDL_SemPost(cond->wait_done); |
207 /* Signal handshake complete */ | 211 |
208 --cond->signals; | 212 /* Signal handshake complete */ |
209 } | 213 --cond->signals; |
210 --cond->waiting; | 214 } |
211 SDL_UnlockMutex(cond->lock); | 215 --cond->waiting; |
212 | 216 SDL_UnlockMutex(cond->lock); |
213 /* Lock the mutex, as is required by condition variable semantics */ | 217 |
214 SDL_LockMutex(mutex); | 218 /* Lock the mutex, as is required by condition variable semantics */ |
215 | 219 SDL_LockMutex(mutex); |
216 return retval; | 220 |
221 return retval; | |
217 } | 222 } |
218 | 223 |
219 /* Wait on the condition variable forever */ | 224 /* Wait on the condition variable forever */ |
220 int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex) | 225 int |
221 { | 226 SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex) |
222 return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT); | 227 { |
223 } | 228 return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT); |
229 } |