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