Mercurial > sdl-ios-xcode
comparison src/thread/SDL_thread.c @ 1668:4da1ee79c9af SDL-1.3
more tweaking indent options
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 29 May 2006 04:04:35 +0000 |
parents | 782fd950bd46 |
children |
comparison
equal
deleted
inserted
replaced
1667:1fddae038bc8 | 1668:4da1ee79c9af |
---|---|
37 static int SDL_numthreads = 0; | 37 static int SDL_numthreads = 0; |
38 static SDL_Thread **SDL_Threads = NULL; | 38 static SDL_Thread **SDL_Threads = NULL; |
39 static SDL_mutex *thread_lock = NULL; | 39 static SDL_mutex *thread_lock = NULL; |
40 | 40 |
41 int | 41 int |
42 SDL_ThreadsInit (void) | 42 SDL_ThreadsInit(void) |
43 { | 43 { |
44 int retval; | 44 int retval; |
45 | 45 |
46 retval = 0; | 46 retval = 0; |
47 thread_lock = SDL_CreateMutex (); | 47 thread_lock = SDL_CreateMutex(); |
48 if (thread_lock == NULL) { | 48 if (thread_lock == NULL) { |
49 retval = -1; | 49 retval = -1; |
50 } | 50 } |
51 return (retval); | 51 return (retval); |
52 } | 52 } |
55 If this is called by SDL_Quit(), we don't know whether or not we should | 55 If this is called by SDL_Quit(), we don't know whether or not we should |
56 clean up threads here. If any threads are still running after this call, | 56 clean up threads here. If any threads are still running after this call, |
57 they will no longer have access to any per-thread data. | 57 they will no longer have access to any per-thread data. |
58 */ | 58 */ |
59 void | 59 void |
60 SDL_ThreadsQuit (void) | 60 SDL_ThreadsQuit(void) |
61 { | 61 { |
62 SDL_mutex *mutex; | 62 SDL_mutex *mutex; |
63 | 63 |
64 mutex = thread_lock; | 64 mutex = thread_lock; |
65 thread_lock = NULL; | 65 thread_lock = NULL; |
66 if (mutex != NULL) { | 66 if (mutex != NULL) { |
67 SDL_DestroyMutex (mutex); | 67 SDL_DestroyMutex(mutex); |
68 } | 68 } |
69 } | 69 } |
70 | 70 |
71 /* Routines for manipulating the thread list */ | 71 /* Routines for manipulating the thread list */ |
72 static void | 72 static void |
73 SDL_AddThread (SDL_Thread * thread) | 73 SDL_AddThread(SDL_Thread * thread) |
74 { | 74 { |
75 /* WARNING: | 75 /* WARNING: |
76 If the very first threads are created simultaneously, then | 76 If the very first threads are created simultaneously, then |
77 there could be a race condition causing memory corruption. | 77 there could be a race condition causing memory corruption. |
78 In practice, this isn't a problem because by definition there | 78 In practice, this isn't a problem because by definition there |
79 is only one thread running the first time this is called. | 79 is only one thread running the first time this is called. |
80 */ | 80 */ |
81 if (!thread_lock) { | 81 if (!thread_lock) { |
82 if (SDL_ThreadsInit () < 0) { | 82 if (SDL_ThreadsInit() < 0) { |
83 return; | 83 return; |
84 } | 84 } |
85 } | 85 } |
86 SDL_mutexP (thread_lock); | 86 SDL_mutexP(thread_lock); |
87 | 87 |
88 /* Expand the list of threads, if necessary */ | 88 /* Expand the list of threads, if necessary */ |
89 #ifdef DEBUG_THREADS | 89 #ifdef DEBUG_THREADS |
90 printf ("Adding thread (%d already - %d max)\n", | 90 printf("Adding thread (%d already - %d max)\n", |
91 SDL_numthreads, SDL_maxthreads); | 91 SDL_numthreads, SDL_maxthreads); |
92 #endif | 92 #endif |
93 if (SDL_numthreads == SDL_maxthreads) { | 93 if (SDL_numthreads == SDL_maxthreads) { |
94 SDL_Thread **threads; | 94 SDL_Thread **threads; |
95 threads = (SDL_Thread **) SDL_realloc (SDL_Threads, | 95 threads = (SDL_Thread **) SDL_realloc(SDL_Threads, |
96 (SDL_maxthreads + | 96 (SDL_maxthreads + |
97 ARRAY_CHUNKSIZE) * | 97 ARRAY_CHUNKSIZE) * |
98 (sizeof *threads)); | 98 (sizeof *threads)); |
99 if (threads == NULL) { | 99 if (threads == NULL) { |
100 SDL_OutOfMemory (); | 100 SDL_OutOfMemory(); |
101 goto done; | 101 goto done; |
102 } | 102 } |
103 SDL_maxthreads += ARRAY_CHUNKSIZE; | 103 SDL_maxthreads += ARRAY_CHUNKSIZE; |
104 SDL_Threads = threads; | 104 SDL_Threads = threads; |
105 } | 105 } |
106 SDL_Threads[SDL_numthreads++] = thread; | 106 SDL_Threads[SDL_numthreads++] = thread; |
107 done: | 107 done: |
108 SDL_mutexV (thread_lock); | 108 SDL_mutexV(thread_lock); |
109 } | 109 } |
110 | 110 |
111 static void | 111 static void |
112 SDL_DelThread (SDL_Thread * thread) | 112 SDL_DelThread(SDL_Thread * thread) |
113 { | 113 { |
114 int i; | 114 int i; |
115 | 115 |
116 if (!thread_lock) { | 116 if (!thread_lock) { |
117 return; | 117 return; |
118 } | 118 } |
119 SDL_mutexP (thread_lock); | 119 SDL_mutexP(thread_lock); |
120 for (i = 0; i < SDL_numthreads; ++i) { | 120 for (i = 0; i < SDL_numthreads; ++i) { |
121 if (thread == SDL_Threads[i]) { | 121 if (thread == SDL_Threads[i]) { |
122 break; | 122 break; |
123 } | 123 } |
124 } | 124 } |
128 SDL_Threads[i] = SDL_Threads[i + 1]; | 128 SDL_Threads[i] = SDL_Threads[i + 1]; |
129 ++i; | 129 ++i; |
130 } | 130 } |
131 } else { | 131 } else { |
132 SDL_maxthreads = 0; | 132 SDL_maxthreads = 0; |
133 SDL_free (SDL_Threads); | 133 SDL_free(SDL_Threads); |
134 SDL_Threads = NULL; | 134 SDL_Threads = NULL; |
135 } | 135 } |
136 #ifdef DEBUG_THREADS | 136 #ifdef DEBUG_THREADS |
137 printf ("Deleting thread (%d left - %d max)\n", | 137 printf("Deleting thread (%d left - %d max)\n", |
138 SDL_numthreads, SDL_maxthreads); | 138 SDL_numthreads, SDL_maxthreads); |
139 #endif | 139 #endif |
140 } | 140 } |
141 SDL_mutexV (thread_lock); | 141 SDL_mutexV(thread_lock); |
142 | 142 |
143 if (SDL_Threads == NULL) { | 143 if (SDL_Threads == NULL) { |
144 SDL_ThreadsQuit (); | 144 SDL_ThreadsQuit(); |
145 } | 145 } |
146 } | 146 } |
147 | 147 |
148 /* The default (non-thread-safe) global error variable */ | 148 /* The default (non-thread-safe) global error variable */ |
149 static SDL_error SDL_global_error; | 149 static SDL_error SDL_global_error; |
150 | 150 |
151 /* Routine to get the thread-specific error variable */ | 151 /* Routine to get the thread-specific error variable */ |
152 SDL_error * | 152 SDL_error * |
153 SDL_GetErrBuf (void) | 153 SDL_GetErrBuf(void) |
154 { | 154 { |
155 SDL_error *errbuf; | 155 SDL_error *errbuf; |
156 | 156 |
157 errbuf = &SDL_global_error; | 157 errbuf = &SDL_global_error; |
158 if (SDL_Threads) { | 158 if (SDL_Threads) { |
159 int i; | 159 int i; |
160 Uint32 this_thread; | 160 Uint32 this_thread; |
161 | 161 |
162 this_thread = SDL_ThreadID (); | 162 this_thread = SDL_ThreadID(); |
163 SDL_mutexP (thread_lock); | 163 SDL_mutexP(thread_lock); |
164 for (i = 0; i < SDL_numthreads; ++i) { | 164 for (i = 0; i < SDL_numthreads; ++i) { |
165 if (this_thread == SDL_Threads[i]->threadid) { | 165 if (this_thread == SDL_Threads[i]->threadid) { |
166 errbuf = &SDL_Threads[i]->errbuf; | 166 errbuf = &SDL_Threads[i]->errbuf; |
167 break; | 167 break; |
168 } | 168 } |
169 } | 169 } |
170 SDL_mutexV (thread_lock); | 170 SDL_mutexV(thread_lock); |
171 } | 171 } |
172 return (errbuf); | 172 return (errbuf); |
173 } | 173 } |
174 | 174 |
175 | 175 |
181 SDL_Thread *info; | 181 SDL_Thread *info; |
182 SDL_sem *wait; | 182 SDL_sem *wait; |
183 } thread_args; | 183 } thread_args; |
184 | 184 |
185 void | 185 void |
186 SDL_RunThread (void *data) | 186 SDL_RunThread(void *data) |
187 { | 187 { |
188 thread_args *args; | 188 thread_args *args; |
189 int (SDLCALL * userfunc) (void *); | 189 int (SDLCALL * userfunc) (void *); |
190 void *userdata; | 190 void *userdata; |
191 int *statusloc; | 191 int *statusloc; |
192 | 192 |
193 /* Perform any system-dependent setup | 193 /* Perform any system-dependent setup |
194 - this function cannot fail, and cannot use SDL_SetError() | 194 - this function cannot fail, and cannot use SDL_SetError() |
195 */ | 195 */ |
196 SDL_SYS_SetupThread (); | 196 SDL_SYS_SetupThread(); |
197 | 197 |
198 /* Get the thread id */ | 198 /* Get the thread id */ |
199 args = (thread_args *) data; | 199 args = (thread_args *) data; |
200 args->info->threadid = SDL_ThreadID (); | 200 args->info->threadid = SDL_ThreadID(); |
201 | 201 |
202 /* Figure out what function to run */ | 202 /* Figure out what function to run */ |
203 userfunc = args->func; | 203 userfunc = args->func; |
204 userdata = args->data; | 204 userdata = args->data; |
205 statusloc = &args->info->status; | 205 statusloc = &args->info->status; |
206 | 206 |
207 /* Wake up the parent thread */ | 207 /* Wake up the parent thread */ |
208 SDL_SemPost (args->wait); | 208 SDL_SemPost(args->wait); |
209 | 209 |
210 /* Run the function */ | 210 /* Run the function */ |
211 *statusloc = userfunc (userdata); | 211 *statusloc = userfunc(userdata); |
212 } | 212 } |
213 | 213 |
214 #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD | 214 #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD |
215 #undef SDL_CreateThread | 215 #undef SDL_CreateThread |
216 DECLSPEC SDL_Thread *SDLCALL | 216 DECLSPEC SDL_Thread *SDLCALL |
217 SDL_CreateThread (int (SDLCALL * fn) (void *), void *data, | 217 SDL_CreateThread(int (SDLCALL * fn) (void *), void *data, |
218 pfnSDL_CurrentBeginThread pfnBeginThread, | 218 pfnSDL_CurrentBeginThread pfnBeginThread, |
219 pfnSDL_CurrentEndThread pfnEndThread) | 219 pfnSDL_CurrentEndThread pfnEndThread) |
220 #else | 220 #else |
221 DECLSPEC SDL_Thread *SDLCALL | 221 DECLSPEC SDL_Thread *SDLCALL |
222 SDL_CreateThread (int (SDLCALL * fn) (void *), void *data) | 222 SDL_CreateThread(int (SDLCALL * fn) (void *), void *data) |
223 #endif | 223 #endif |
224 { | 224 { |
225 SDL_Thread *thread; | 225 SDL_Thread *thread; |
226 thread_args *args; | 226 thread_args *args; |
227 int ret; | 227 int ret; |
228 | 228 |
229 /* Allocate memory for the thread info structure */ | 229 /* Allocate memory for the thread info structure */ |
230 thread = (SDL_Thread *) SDL_malloc (sizeof (*thread)); | 230 thread = (SDL_Thread *) SDL_malloc(sizeof(*thread)); |
231 if (thread == NULL) { | 231 if (thread == NULL) { |
232 SDL_OutOfMemory (); | 232 SDL_OutOfMemory(); |
233 return (NULL); | 233 return (NULL); |
234 } | 234 } |
235 SDL_memset (thread, 0, (sizeof *thread)); | 235 SDL_memset(thread, 0, (sizeof *thread)); |
236 thread->status = -1; | 236 thread->status = -1; |
237 | 237 |
238 /* Set up the arguments for the thread */ | 238 /* Set up the arguments for the thread */ |
239 args = (thread_args *) SDL_malloc (sizeof (*args)); | 239 args = (thread_args *) SDL_malloc(sizeof(*args)); |
240 if (args == NULL) { | 240 if (args == NULL) { |
241 SDL_OutOfMemory (); | 241 SDL_OutOfMemory(); |
242 SDL_free (thread); | 242 SDL_free(thread); |
243 return (NULL); | 243 return (NULL); |
244 } | 244 } |
245 args->func = fn; | 245 args->func = fn; |
246 args->data = data; | 246 args->data = data; |
247 args->info = thread; | 247 args->info = thread; |
248 args->wait = SDL_CreateSemaphore (0); | 248 args->wait = SDL_CreateSemaphore(0); |
249 if (args->wait == NULL) { | 249 if (args->wait == NULL) { |
250 SDL_free (thread); | 250 SDL_free(thread); |
251 SDL_free (args); | 251 SDL_free(args); |
252 return (NULL); | 252 return (NULL); |
253 } | 253 } |
254 | 254 |
255 /* Add the thread to the list of available threads */ | 255 /* Add the thread to the list of available threads */ |
256 SDL_AddThread (thread); | 256 SDL_AddThread(thread); |
257 | 257 |
258 /* Create the thread and go! */ | 258 /* Create the thread and go! */ |
259 #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD | 259 #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD |
260 ret = SDL_SYS_CreateThread (thread, args, pfnBeginThread, pfnEndThread); | 260 ret = SDL_SYS_CreateThread(thread, args, pfnBeginThread, pfnEndThread); |
261 #else | 261 #else |
262 ret = SDL_SYS_CreateThread (thread, args); | 262 ret = SDL_SYS_CreateThread(thread, args); |
263 #endif | 263 #endif |
264 if (ret >= 0) { | 264 if (ret >= 0) { |
265 /* Wait for the thread function to use arguments */ | 265 /* Wait for the thread function to use arguments */ |
266 SDL_SemWait (args->wait); | 266 SDL_SemWait(args->wait); |
267 } else { | 267 } else { |
268 /* Oops, failed. Gotta free everything */ | 268 /* Oops, failed. Gotta free everything */ |
269 SDL_DelThread (thread); | 269 SDL_DelThread(thread); |
270 SDL_free (thread); | 270 SDL_free(thread); |
271 thread = NULL; | 271 thread = NULL; |
272 } | 272 } |
273 SDL_DestroySemaphore (args->wait); | 273 SDL_DestroySemaphore(args->wait); |
274 SDL_free (args); | 274 SDL_free(args); |
275 | 275 |
276 /* Everything is running now */ | 276 /* Everything is running now */ |
277 return (thread); | 277 return (thread); |
278 } | 278 } |
279 | 279 |
280 void | 280 void |
281 SDL_WaitThread (SDL_Thread * thread, int *status) | 281 SDL_WaitThread(SDL_Thread * thread, int *status) |
282 { | 282 { |
283 if (thread) { | 283 if (thread) { |
284 SDL_SYS_WaitThread (thread); | 284 SDL_SYS_WaitThread(thread); |
285 if (status) { | 285 if (status) { |
286 *status = thread->status; | 286 *status = thread->status; |
287 } | 287 } |
288 SDL_DelThread (thread); | 288 SDL_DelThread(thread); |
289 SDL_free (thread); | 289 SDL_free(thread); |
290 } | 290 } |
291 } | 291 } |
292 | 292 |
293 Uint32 | 293 Uint32 |
294 SDL_GetThreadID (SDL_Thread * thread) | 294 SDL_GetThreadID(SDL_Thread * thread) |
295 { | 295 { |
296 Uint32 id; | 296 Uint32 id; |
297 | 297 |
298 if (thread) { | 298 if (thread) { |
299 id = thread->threadid; | 299 id = thread->threadid; |
300 } else { | 300 } else { |
301 id = SDL_ThreadID (); | 301 id = SDL_ThreadID(); |
302 } | 302 } |
303 return (id); | 303 return (id); |
304 } | 304 } |
305 | 305 |
306 void | 306 void |
307 SDL_KillThread (SDL_Thread * thread) | 307 SDL_KillThread(SDL_Thread * thread) |
308 { | 308 { |
309 if (thread) { | 309 if (thread) { |
310 SDL_SYS_KillThread (thread); | 310 SDL_SYS_KillThread(thread); |
311 SDL_WaitThread (thread, NULL); | 311 SDL_WaitThread(thread, NULL); |
312 } | 312 } |
313 } | 313 } |
314 | 314 |
315 /* vi: set ts=4 sw=4 expandtab: */ | 315 /* vi: set ts=4 sw=4 expandtab: */ |