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: */