Mercurial > sdl-ios-xcode
comparison src/thread/amigaos/SDL_thread.c @ 1662:782fd950bd46 SDL-1.3
Revamp of the video system in progress - adding support for multiple displays, multiple windows, and a full video mode selection API.
WARNING: None of the video drivers have been updated for the new API yet! The API is still under design and very fluid.
The code is now run through a consistent indent format:
indent -i4 -nut -nsc -br -ce
The headers are being converted to automatically generate doxygen documentation.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sun, 28 May 2006 13:04:16 +0000 |
parents | d910939febfa |
children | 4da1ee79c9af |
comparison
equal
deleted
inserted
replaced
1661:281d3f4870e5 | 1662:782fd950bd46 |
---|---|
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 struct SignalSemaphore thread_lock; | 39 static struct SignalSemaphore thread_lock; |
40 int thread_lock_created = 0; | 40 int thread_lock_created = 0; |
41 | 41 |
42 int SDL_ThreadsInit(void) | 42 int |
43 { | 43 SDL_ThreadsInit (void) |
44 InitSemaphore(&thread_lock); | 44 { |
45 thread_lock_created=1; | 45 InitSemaphore (&thread_lock); |
46 return 0; | 46 thread_lock_created = 1; |
47 return 0; | |
47 } | 48 } |
48 | 49 |
49 /* This should never be called... | 50 /* This should never be called... |
50 If this is called by SDL_Quit(), we don't know whether or not we should | 51 If this is called by SDL_Quit(), we don't know whether or not we should |
51 clean up threads here. If any threads are still running after this call, | 52 clean up threads here. If any threads are still running after this call, |
52 they will no longer have access to any per-thread data. | 53 they will no longer have access to any per-thread data. |
53 */ | 54 */ |
54 void SDL_ThreadsQuit() | 55 void |
55 { | 56 SDL_ThreadsQuit () |
56 thread_lock_created=0; | 57 { |
58 thread_lock_created = 0; | |
57 } | 59 } |
58 | 60 |
59 /* Routines for manipulating the thread list */ | 61 /* Routines for manipulating the thread list */ |
60 static void SDL_AddThread(SDL_Thread *thread) | 62 static void |
61 { | 63 SDL_AddThread (SDL_Thread * thread) |
62 SDL_Thread **threads; | 64 { |
63 | 65 SDL_Thread **threads; |
64 /* WARNING: | 66 |
65 If the very first threads are created simultaneously, then | 67 /* WARNING: |
66 there could be a race condition causing memory corruption. | 68 If the very first threads are created simultaneously, then |
67 In practice, this isn't a problem because by definition there | 69 there could be a race condition causing memory corruption. |
68 is only one thread running the first time this is called. | 70 In practice, this isn't a problem because by definition there |
69 */ | 71 is only one thread running the first time this is called. |
70 if ( !thread_lock_created ) { | 72 */ |
71 if ( SDL_ThreadsInit() < 0 ) { | 73 if (!thread_lock_created) { |
72 return; | 74 if (SDL_ThreadsInit () < 0) { |
73 } | 75 return; |
74 } | 76 } |
75 ObtainSemaphore(&thread_lock); | 77 } |
76 | 78 ObtainSemaphore (&thread_lock); |
77 /* Expand the list of threads, if necessary */ | 79 |
80 /* Expand the list of threads, if necessary */ | |
78 #ifdef DEBUG_THREADS | 81 #ifdef DEBUG_THREADS |
79 printf("Adding thread (%d already - %d max)\n", | 82 printf ("Adding thread (%d already - %d max)\n", |
80 SDL_numthreads, SDL_maxthreads); | 83 SDL_numthreads, SDL_maxthreads); |
81 #endif | 84 #endif |
82 if ( SDL_numthreads == SDL_maxthreads ) { | 85 if (SDL_numthreads == SDL_maxthreads) { |
83 threads=(SDL_Thread **)SDL_malloc((SDL_maxthreads+ARRAY_CHUNKSIZE)* | 86 threads = |
84 (sizeof *threads)); | 87 (SDL_Thread **) SDL_malloc ((SDL_maxthreads + ARRAY_CHUNKSIZE) * |
85 if ( threads == NULL ) { | 88 (sizeof *threads)); |
86 SDL_OutOfMemory(); | 89 if (threads == NULL) { |
87 goto done; | 90 SDL_OutOfMemory (); |
88 } | 91 goto done; |
89 SDL_memcpy(threads, SDL_Threads, SDL_numthreads*(sizeof *threads)); | 92 } |
90 SDL_maxthreads += ARRAY_CHUNKSIZE; | 93 SDL_memcpy (threads, SDL_Threads, SDL_numthreads * (sizeof *threads)); |
91 if ( SDL_Threads ) { | 94 SDL_maxthreads += ARRAY_CHUNKSIZE; |
92 SDL_free(SDL_Threads); | 95 if (SDL_Threads) { |
93 } | 96 SDL_free (SDL_Threads); |
94 SDL_Threads = threads; | 97 } |
95 } | 98 SDL_Threads = threads; |
96 SDL_Threads[SDL_numthreads++] = thread; | 99 } |
97 done: | 100 SDL_Threads[SDL_numthreads++] = thread; |
98 ReleaseSemaphore(&thread_lock); | 101 done: |
99 } | 102 ReleaseSemaphore (&thread_lock); |
100 | 103 } |
101 static void SDL_DelThread(SDL_Thread *thread) | 104 |
102 { | 105 static void |
103 int i; | 106 SDL_DelThread (SDL_Thread * thread) |
104 | 107 { |
105 if ( thread_lock_created ) { | 108 int i; |
106 ObtainSemaphore(&thread_lock); | 109 |
107 for ( i=0; i<SDL_numthreads; ++i ) { | 110 if (thread_lock_created) { |
108 if ( thread == SDL_Threads[i] ) { | 111 ObtainSemaphore (&thread_lock); |
109 break; | 112 for (i = 0; i < SDL_numthreads; ++i) { |
110 } | 113 if (thread == SDL_Threads[i]) { |
111 } | 114 break; |
112 if ( i < SDL_numthreads ) { | 115 } |
113 --SDL_numthreads; | 116 } |
114 while ( i < SDL_numthreads ) { | 117 if (i < SDL_numthreads) { |
115 SDL_Threads[i] = SDL_Threads[i+1]; | 118 --SDL_numthreads; |
116 ++i; | 119 while (i < SDL_numthreads) { |
117 } | 120 SDL_Threads[i] = SDL_Threads[i + 1]; |
121 ++i; | |
122 } | |
118 #ifdef DEBUG_THREADS | 123 #ifdef DEBUG_THREADS |
119 printf("Deleting thread (%d left - %d max)\n", | 124 printf ("Deleting thread (%d left - %d max)\n", |
120 SDL_numthreads, SDL_maxthreads); | 125 SDL_numthreads, SDL_maxthreads); |
121 #endif | 126 #endif |
122 } | 127 } |
123 ReleaseSemaphore(&thread_lock); | 128 ReleaseSemaphore (&thread_lock); |
124 } | 129 } |
125 } | 130 } |
126 | 131 |
127 /* The default (non-thread-safe) global error variable */ | 132 /* The default (non-thread-safe) global error variable */ |
128 static SDL_error SDL_global_error; | 133 static SDL_error SDL_global_error; |
129 | 134 |
130 /* Routine to get the thread-specific error variable */ | 135 /* Routine to get the thread-specific error variable */ |
131 SDL_error *SDL_GetErrBuf(void) | 136 SDL_error * |
132 { | 137 SDL_GetErrBuf (void) |
133 SDL_error *errbuf; | 138 { |
134 | 139 SDL_error *errbuf; |
135 errbuf = &SDL_global_error; | 140 |
136 if ( SDL_Threads ) { | 141 errbuf = &SDL_global_error; |
137 int i; | 142 if (SDL_Threads) { |
138 Uint32 this_thread; | 143 int i; |
139 | 144 Uint32 this_thread; |
140 this_thread = SDL_ThreadID(); | 145 |
141 ObtainSemaphore(&thread_lock); | 146 this_thread = SDL_ThreadID (); |
142 for ( i=0; i<SDL_numthreads; ++i ) { | 147 ObtainSemaphore (&thread_lock); |
143 if ( this_thread == SDL_Threads[i]->threadid ) { | 148 for (i = 0; i < SDL_numthreads; ++i) { |
144 errbuf = &SDL_Threads[i]->errbuf; | 149 if (this_thread == SDL_Threads[i]->threadid) { |
145 break; | 150 errbuf = &SDL_Threads[i]->errbuf; |
146 } | 151 break; |
147 } | 152 } |
148 ReleaseSemaphore(&thread_lock); | 153 } |
149 } | 154 ReleaseSemaphore (&thread_lock); |
150 return(errbuf); | 155 } |
156 return (errbuf); | |
151 } | 157 } |
152 | 158 |
153 | 159 |
154 /* Arguments and callback to setup and run the user thread function */ | 160 /* Arguments and callback to setup and run the user thread function */ |
155 typedef struct { | 161 typedef struct |
156 int (*func)(void *); | 162 { |
157 void *data; | 163 int (*func) (void *); |
158 SDL_Thread *info; | 164 void *data; |
159 struct Task *wait; | 165 SDL_Thread *info; |
166 struct Task *wait; | |
160 } thread_args; | 167 } thread_args; |
161 | 168 |
162 void SDL_RunThread(void *data) | 169 void |
163 { | 170 SDL_RunThread (void *data) |
164 thread_args *args; | 171 { |
165 int (*userfunc)(void *); | 172 thread_args *args; |
166 void *userdata; | 173 int (*userfunc) (void *); |
167 int *statusloc; | 174 void *userdata; |
168 | 175 int *statusloc; |
169 /* Perform any system-dependent setup | 176 |
170 - this function cannot fail, and cannot use SDL_SetError() | 177 /* Perform any system-dependent setup |
171 */ | 178 - this function cannot fail, and cannot use SDL_SetError() |
172 SDL_SYS_SetupThread(); | 179 */ |
173 | 180 SDL_SYS_SetupThread (); |
174 /* Get the thread id */ | 181 |
175 args = (thread_args *)data; | 182 /* Get the thread id */ |
176 args->info->threadid = SDL_ThreadID(); | 183 args = (thread_args *) data; |
177 | 184 args->info->threadid = SDL_ThreadID (); |
178 /* Figure out what function to run */ | 185 |
179 userfunc = args->func; | 186 /* Figure out what function to run */ |
180 userdata = args->data; | 187 userfunc = args->func; |
181 statusloc = &args->info->status; | 188 userdata = args->data; |
182 | 189 statusloc = &args->info->status; |
183 /* Wake up the parent thread */ | 190 |
184 Signal(args->wait,SIGBREAKF_CTRL_E); | 191 /* Wake up the parent thread */ |
185 | 192 Signal (args->wait, SIGBREAKF_CTRL_E); |
186 /* Run the function */ | 193 |
187 *statusloc = userfunc(userdata); | 194 /* Run the function */ |
188 } | 195 *statusloc = userfunc (userdata); |
189 | 196 } |
190 SDL_Thread *SDL_CreateThread(int (*fn)(void *), void *data) | 197 |
191 { | 198 SDL_Thread * |
192 SDL_Thread *thread; | 199 SDL_CreateThread (int (*fn) (void *), void *data) |
193 thread_args *args; | 200 { |
194 int ret; | 201 SDL_Thread *thread; |
195 | 202 thread_args *args; |
196 /* Allocate memory for the thread info structure */ | 203 int ret; |
197 thread = (SDL_Thread *)SDL_malloc(sizeof(*thread)); | 204 |
198 if ( thread == NULL ) { | 205 /* Allocate memory for the thread info structure */ |
199 SDL_OutOfMemory(); | 206 thread = (SDL_Thread *) SDL_malloc (sizeof (*thread)); |
200 return(NULL); | 207 if (thread == NULL) { |
201 } | 208 SDL_OutOfMemory (); |
202 SDL_memset(thread, 0, (sizeof *thread)); | 209 return (NULL); |
203 thread->status = -1; | 210 } |
204 | 211 SDL_memset (thread, 0, (sizeof *thread)); |
205 /* Set up the arguments for the thread */ | 212 thread->status = -1; |
206 args = (thread_args *)SDL_malloc(sizeof(*args)); | 213 |
207 if ( args == NULL ) { | 214 /* Set up the arguments for the thread */ |
208 SDL_OutOfMemory(); | 215 args = (thread_args *) SDL_malloc (sizeof (*args)); |
209 SDL_free(thread); | 216 if (args == NULL) { |
210 return(NULL); | 217 SDL_OutOfMemory (); |
211 } | 218 SDL_free (thread); |
212 args->func = fn; | 219 return (NULL); |
213 args->data = data; | 220 } |
214 args->info = thread; | 221 args->func = fn; |
215 args->wait = FindTask(NULL); | 222 args->data = data; |
216 if ( args->wait == NULL ) { | 223 args->info = thread; |
217 SDL_free(thread); | 224 args->wait = FindTask (NULL); |
218 SDL_free(args); | 225 if (args->wait == NULL) { |
219 SDL_OutOfMemory(); | 226 SDL_free (thread); |
220 return(NULL); | 227 SDL_free (args); |
221 } | 228 SDL_OutOfMemory (); |
222 | 229 return (NULL); |
223 /* Add the thread to the list of available threads */ | 230 } |
224 SDL_AddThread(thread); | 231 |
225 | 232 /* Add the thread to the list of available threads */ |
226 D(bug("Starting thread...\n")); | 233 SDL_AddThread (thread); |
227 | 234 |
228 /* Create the thread and go! */ | 235 D (bug ("Starting thread...\n")); |
229 ret = SDL_SYS_CreateThread(thread, args); | 236 |
230 if ( ret >= 0 ) { | 237 /* Create the thread and go! */ |
231 D(bug("Waiting for thread CTRL_E...\n")); | 238 ret = SDL_SYS_CreateThread (thread, args); |
232 /* Wait for the thread function to use arguments */ | 239 if (ret >= 0) { |
233 Wait(SIGBREAKF_CTRL_E); | 240 D (bug ("Waiting for thread CTRL_E...\n")); |
234 D(bug(" Arrived.")); | 241 /* Wait for the thread function to use arguments */ |
235 } else { | 242 Wait (SIGBREAKF_CTRL_E); |
236 /* Oops, failed. Gotta free everything */ | 243 D (bug (" Arrived.")); |
237 SDL_DelThread(thread); | 244 } else { |
238 SDL_free(thread); | 245 /* Oops, failed. Gotta free everything */ |
239 thread = NULL; | 246 SDL_DelThread (thread); |
240 } | 247 SDL_free (thread); |
241 SDL_free(args); | 248 thread = NULL; |
242 | 249 } |
243 /* Everything is running now */ | 250 SDL_free (args); |
244 return(thread); | 251 |
245 } | 252 /* Everything is running now */ |
246 | 253 return (thread); |
247 void SDL_WaitThread(SDL_Thread *thread, int *status) | 254 } |
248 { | 255 |
249 if ( thread ) { | 256 void |
250 SDL_SYS_WaitThread(thread); | 257 SDL_WaitThread (SDL_Thread * thread, int *status) |
251 if ( status ) { | 258 { |
252 *status = thread->status; | 259 if (thread) { |
253 } | 260 SDL_SYS_WaitThread (thread); |
254 SDL_DelThread(thread); | 261 if (status) { |
255 SDL_free(thread); | 262 *status = thread->status; |
256 } | 263 } |
257 } | 264 SDL_DelThread (thread); |
258 | 265 SDL_free (thread); |
259 Uint32 SDL_GetThreadID(SDL_Thread *thread) | 266 } |
260 { | 267 } |
261 Uint32 id; | 268 |
262 | 269 Uint32 |
263 if ( thread ) { | 270 SDL_GetThreadID (SDL_Thread * thread) |
264 id = thread->threadid; | 271 { |
265 } else { | 272 Uint32 id; |
266 id = SDL_ThreadID(); | 273 |
267 } | 274 if (thread) { |
268 return(id); | 275 id = thread->threadid; |
269 } | 276 } else { |
270 | 277 id = SDL_ThreadID (); |
271 void SDL_KillThread(SDL_Thread *thread) | 278 } |
272 { | 279 return (id); |
273 if ( thread ) { | 280 } |
274 SDL_SYS_KillThread(thread); | 281 |
275 SDL_WaitThread(thread, NULL); | 282 void |
276 } | 283 SDL_KillThread (SDL_Thread * thread) |
277 } | 284 { |
278 | 285 if (thread) { |
286 SDL_SYS_KillThread (thread); | |
287 SDL_WaitThread (thread, NULL); | |
288 } | |
289 } | |
290 | |
291 /* vi: set ts=4 sw=4 expandtab: */ |