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 }