summaryrefslogtreecommitdiff
path: root/uisimulator/sdl/thread-sdl.c
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-10-16 01:25:17 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-10-16 01:25:17 +0000
commita9b2fb5ee3114fe835f6515b6aeae7454f66d821 (patch)
treefc4e96d0c1f215565918406c8827b16b806c1345 /uisimulator/sdl/thread-sdl.c
parenta3fbbc9fa7e12fd3fce122bbd235dc362050e024 (diff)
downloadrockbox-a9b2fb5ee3114fe835f6515b6aeae7454f66d821.tar.gz
rockbox-a9b2fb5ee3114fe835f6515b6aeae7454f66d821.zip
Finally full multicore support for PortalPlayer 502x targets with an eye towards the possibility of other types. All SVN targets the low-lag code to speed up blocking operations. Most files are modified here simple due to a name change to actually support a real event object and a param change to create_thread. Add some use of new features but just sit on things for a bit and leave full integration for later. Work will continue on to address size on sensitive targets and simplify things if possible. Any PP target having problems with SWP can easily be changed to sw corelocks with one #define change in config.h though only PP5020 has shown an issue and seems to work without any difficulties.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15134 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'uisimulator/sdl/thread-sdl.c')
-rw-r--r--uisimulator/sdl/thread-sdl.c160
1 files changed, 105 insertions, 55 deletions
diff --git a/uisimulator/sdl/thread-sdl.c b/uisimulator/sdl/thread-sdl.c
index 0bd7d2534e..6a3c4af9eb 100644
--- a/uisimulator/sdl/thread-sdl.c
+++ b/uisimulator/sdl/thread-sdl.c
@@ -131,7 +131,7 @@ bool thread_sdl_init(void *param)
131 running->stack = " "; 131 running->stack = " ";
132 running->stack_size = 8; 132 running->stack_size = 8;
133 running->name = "main"; 133 running->name = "main";
134 running->statearg = STATE_RUNNING; 134 running->state = STATE_RUNNING;
135 running->context.c = SDL_CreateCond(); 135 running->context.c = SDL_CreateCond();
136 136
137 if (running->context.c == NULL) 137 if (running->context.c == NULL)
@@ -154,43 +154,55 @@ bool thread_sdl_init(void *param)
154 return true; 154 return true;
155} 155}
156 156
157void thread_sdl_lock(void)
158{
159 SDL_LockMutex(m);
160}
161
162void thread_sdl_unlock(void)
163{
164 SDL_UnlockMutex(m);
165}
166
157static int find_empty_thread_slot(void) 167static int find_empty_thread_slot(void)
158{ 168{
159 int n; 169 int n;
160 170
161 for (n = 0; n < MAXTHREADS; n++) 171 for (n = 0; n < MAXTHREADS; n++)
162 { 172 {
163 if (threads[n].name == NULL) 173 int state = threads[n].state;
174
175 if (state == STATE_KILLED)
164 break; 176 break;
165 } 177 }
166 178
167 return n; 179 return n;
168} 180}
169 181
170static void add_to_list(struct thread_entry **list, 182static void add_to_list_l(struct thread_entry **list,
171 struct thread_entry *thread) 183 struct thread_entry *thread)
172{ 184{
173 if (*list == NULL) 185 if (*list == NULL)
174 { 186 {
175 /* Insert into unoccupied list */ 187 /* Insert into unoccupied list */
176 thread->next = thread; 188 thread->l.next = thread;
177 thread->prev = thread; 189 thread->l.prev = thread;
178 *list = thread; 190 *list = thread;
179 } 191 }
180 else 192 else
181 { 193 {
182 /* Insert last */ 194 /* Insert last */
183 thread->next = *list; 195 thread->l.next = *list;
184 thread->prev = (*list)->prev; 196 thread->l.prev = (*list)->l.prev;
185 thread->prev->next = thread; 197 thread->l.prev->l.next = thread;
186 (*list)->prev = thread; 198 (*list)->l.prev = thread;
187 } 199 }
188} 200}
189 201
190static void remove_from_list(struct thread_entry **list, 202static void remove_from_list_l(struct thread_entry **list,
191 struct thread_entry *thread) 203 struct thread_entry *thread)
192{ 204{
193 if (thread == thread->next) 205 if (thread == thread->l.next)
194 { 206 {
195 /* The only item */ 207 /* The only item */
196 *list = NULL; 208 *list = NULL;
@@ -200,12 +212,12 @@ static void remove_from_list(struct thread_entry **list,
200 if (thread == *list) 212 if (thread == *list)
201 { 213 {
202 /* List becomes next item */ 214 /* List becomes next item */
203 *list = thread->next; 215 *list = thread->l.next;
204 } 216 }
205 217
206 /* Fix links to jump over the removed entry. */ 218 /* Fix links to jump over the removed entry. */
207 thread->prev->next = thread->next; 219 thread->l.prev->l.next = thread->l.next;
208 thread->next->prev = thread->prev; 220 thread->l.next->l.prev = thread->l.prev;
209} 221}
210 222
211struct thread_entry *thread_get_current(void) 223struct thread_entry *thread_get_current(void)
@@ -213,17 +225,7 @@ struct thread_entry *thread_get_current(void)
213 return running; 225 return running;
214} 226}
215 227
216void thread_sdl_lock(void) 228void switch_thread(struct thread_entry *old)
217{
218 SDL_LockMutex(m);
219}
220
221void thread_sdl_unlock(void)
222{
223 SDL_UnlockMutex(m);
224}
225
226void switch_thread(bool save_context, struct thread_entry **blocked_list)
227{ 229{
228 struct thread_entry *current = running; 230 struct thread_entry *current = running;
229 231
@@ -235,7 +237,7 @@ void switch_thread(bool save_context, struct thread_entry **blocked_list)
235 if (threads_exit) 237 if (threads_exit)
236 remove_thread(NULL); 238 remove_thread(NULL);
237 239
238 (void)save_context; (void)blocked_list; 240 (void)old;
239} 241}
240 242
241void sleep_thread(int ticks) 243void sleep_thread(int ticks)
@@ -244,7 +246,7 @@ void sleep_thread(int ticks)
244 int rem; 246 int rem;
245 247
246 current = running; 248 current = running;
247 current->statearg = STATE_SLEEPING; 249 current->state = STATE_SLEEPING;
248 250
249 rem = (SDL_GetTicks() - start_tick) % (1000/HZ); 251 rem = (SDL_GetTicks() - start_tick) % (1000/HZ);
250 if (rem < 0) 252 if (rem < 0)
@@ -267,7 +269,7 @@ void sleep_thread(int ticks)
267 269
268 running = current; 270 running = current;
269 271
270 current->statearg = STATE_RUNNING; 272 current->state = STATE_RUNNING;
271 273
272 if (threads_exit) 274 if (threads_exit)
273 remove_thread(NULL); 275 remove_thread(NULL);
@@ -289,10 +291,21 @@ int runthread(void *data)
289 if (setjmp(*current_jmpbuf) == 0) 291 if (setjmp(*current_jmpbuf) == 0)
290 { 292 {
291 /* Run the thread routine */ 293 /* Run the thread routine */
292 current->context.start(); 294 if (current->state == STATE_FROZEN)
293 THREAD_SDL_DEBUGF("Thread Done: %d (%s)\n", 295 {
294 current - threads, THREAD_SDL_GET_NAME(current)); 296 SDL_CondWait(current->context.c, m);
295 /* Thread routine returned - suicide */ 297 running = current;
298
299 }
300
301 if (!threads_exit)
302 {
303 current->context.start();
304 THREAD_SDL_DEBUGF("Thread Done: %d (%s)\n",
305 current - threads, THREAD_SDL_GET_NAME(current));
306 /* Thread routine returned - suicide */
307 }
308
296 remove_thread(NULL); 309 remove_thread(NULL);
297 } 310 }
298 else 311 else
@@ -306,7 +319,7 @@ int runthread(void *data)
306 319
307struct thread_entry* 320struct thread_entry*
308 create_thread(void (*function)(void), void* stack, int stack_size, 321 create_thread(void (*function)(void), void* stack, int stack_size,
309 const char *name) 322 unsigned flags, const char *name)
310{ 323{
311 /** Avoid compiler warnings */ 324 /** Avoid compiler warnings */
312 SDL_Thread* t; 325 SDL_Thread* t;
@@ -340,7 +353,8 @@ struct thread_entry*
340 threads[slot].stack = stack; 353 threads[slot].stack = stack;
341 threads[slot].stack_size = stack_size; 354 threads[slot].stack_size = stack_size;
342 threads[slot].name = name; 355 threads[slot].name = name;
343 threads[slot].statearg = STATE_RUNNING; 356 threads[slot].state = (flags & CREATE_THREAD_FROZEN) ?
357 STATE_FROZEN : STATE_RUNNING;
344 threads[slot].context.start = function; 358 threads[slot].context.start = function;
345 threads[slot].context.t = t; 359 threads[slot].context.t = t;
346 threads[slot].context.c = cond; 360 threads[slot].context.c = cond;
@@ -351,12 +365,13 @@ struct thread_entry*
351 return &threads[slot]; 365 return &threads[slot];
352} 366}
353 367
354void block_thread(struct thread_entry **list) 368void _block_thread(struct thread_queue *tq)
355{ 369{
356 struct thread_entry *thread = running; 370 struct thread_entry *thread = running;
357 371
358 thread->statearg = STATE_BLOCKED; 372 thread->state = STATE_BLOCKED;
359 add_to_list(list, thread); 373 thread->bqp = tq;
374 add_to_list_l(&tq->queue, thread);
360 375
361 SDL_CondWait(thread->context.c, m); 376 SDL_CondWait(thread->context.c, m);
362 running = thread; 377 running = thread;
@@ -365,44 +380,56 @@ void block_thread(struct thread_entry **list)
365 remove_thread(NULL); 380 remove_thread(NULL);
366} 381}
367 382
368void block_thread_w_tmo(struct thread_entry **list, int ticks) 383void block_thread_w_tmo(struct thread_queue *tq, int ticks)
369{ 384{
370 struct thread_entry *thread = running; 385 struct thread_entry *thread = running;
371 386
372 thread->statearg = STATE_BLOCKED_W_TMO; 387 thread->state = STATE_BLOCKED_W_TMO;
373 add_to_list(list, thread); 388 thread->bqp = tq;
389 add_to_list_l(&tq->queue, thread);
374 390
375 SDL_CondWaitTimeout(thread->context.c, m, (1000/HZ) * ticks); 391 SDL_CondWaitTimeout(thread->context.c, m, (1000/HZ) * ticks);
376 running = thread; 392 running = thread;
377 393
378 if (thread->statearg == STATE_BLOCKED_W_TMO) 394 if (thread->state == STATE_BLOCKED_W_TMO)
379 { 395 {
380 /* Timed out */ 396 /* Timed out */
381 remove_from_list(list, thread); 397 remove_from_list_l(&tq->queue, thread);
382 thread->statearg = STATE_RUNNING; 398 thread->state = STATE_RUNNING;
383 } 399 }
384 400
385 if (threads_exit) 401 if (threads_exit)
386 remove_thread(NULL); 402 remove_thread(NULL);
387} 403}
388 404
389void wakeup_thread(struct thread_entry **list) 405struct thread_entry * _wakeup_thread(struct thread_queue *tq)
390{ 406{
391 struct thread_entry *thread = *list; 407 struct thread_entry *thread = tq->queue;
392 408
393 if (thread == NULL) 409 if (thread == NULL)
394 { 410 {
395 return; 411 return NULL;
396 } 412 }
397 413
398 switch (thread->statearg) 414 switch (thread->state)
399 { 415 {
400 case STATE_BLOCKED: 416 case STATE_BLOCKED:
401 case STATE_BLOCKED_W_TMO: 417 case STATE_BLOCKED_W_TMO:
402 remove_from_list(list, thread); 418 remove_from_list_l(&tq->queue, thread);
403 thread->statearg = STATE_RUNNING; 419 thread->state = STATE_RUNNING;
420 SDL_CondSignal(thread->context.c);
421 return thread;
422 default:
423 return NULL;
424 }
425}
426
427void thread_thaw(struct thread_entry *thread)
428{
429 if (thread->state == STATE_FROZEN)
430 {
431 thread->state = STATE_RUNNING;
404 SDL_CondSignal(thread->context.c); 432 SDL_CondSignal(thread->context.c);
405 break;
406 } 433 }
407} 434}
408 435
@@ -434,12 +461,24 @@ void remove_thread(struct thread_entry *thread)
434 thread->context.t = NULL; 461 thread->context.t = NULL;
435 462
436 if (thread != current) 463 if (thread != current)
464 {
465 switch (thread->state)
466 {
467 case STATE_BLOCKED:
468 case STATE_BLOCKED_W_TMO:
469 /* Remove thread from object it's waiting on */
470 remove_from_list_l(&thread->bqp->queue, thread);
471 break;
472 }
473
437 SDL_CondSignal(c); 474 SDL_CondSignal(c);
475 }
438 476
439 THREAD_SDL_DEBUGF("Removing thread: %d (%s)\n", 477 THREAD_SDL_DEBUGF("Removing thread: %d (%s)\n",
440 thread - threads, THREAD_SDL_GET_NAME(thread)); 478 thread - threads, THREAD_SDL_GET_NAME(thread));
441 479
442 thread->name = NULL; 480 thread_queue_wake_no_listlock(&thread->queue);
481 thread->state = STATE_KILLED;
443 482
444 SDL_DestroyCond(c); 483 SDL_DestroyCond(c);
445 484
@@ -453,15 +492,26 @@ void remove_thread(struct thread_entry *thread)
453 SDL_KillThread(t); 492 SDL_KillThread(t);
454} 493}
455 494
495void thread_wait(struct thread_entry *thread)
496{
497 if (thread == NULL)
498 thread = running;
499
500 if (thread->state != STATE_KILLED)
501 {
502 block_thread_no_listlock(&thread->queue);
503 }
504}
505
456int thread_stack_usage(const struct thread_entry *thread) 506int thread_stack_usage(const struct thread_entry *thread)
457{ 507{
458 return 50; 508 return 50;
459 (void)thread; 509 (void)thread;
460} 510}
461 511
462int thread_get_status(const struct thread_entry *thread) 512unsigned thread_get_status(const struct thread_entry *thread)
463{ 513{
464 return thread->statearg; 514 return thread->state;
465} 515}
466 516
467/* Return name if one or ID if none */ 517/* Return name if one or ID if none */