summaryrefslogtreecommitdiff
path: root/uisimulator/sdl/thread-sdl.c
diff options
context:
space:
mode:
Diffstat (limited to 'uisimulator/sdl/thread-sdl.c')
-rw-r--r--uisimulator/sdl/thread-sdl.c115
1 files changed, 71 insertions, 44 deletions
diff --git a/uisimulator/sdl/thread-sdl.c b/uisimulator/sdl/thread-sdl.c
index 905a017ee0..ab1086dd7d 100644
--- a/uisimulator/sdl/thread-sdl.c
+++ b/uisimulator/sdl/thread-sdl.c
@@ -93,6 +93,38 @@ void thread_sdl_shutdown(void)
93 SDL_DestroyMutex(m); 93 SDL_DestroyMutex(m);
94} 94}
95 95
96static void new_thread_id(unsigned int slot_num,
97 struct thread_entry *thread)
98{
99 unsigned int version =
100 (thread->id + (1u << THREAD_ID_VERSION_SHIFT))
101 & THREAD_ID_VERSION_MASK;
102
103 if (version == 0)
104 version = 1u << THREAD_ID_VERSION_SHIFT;
105
106 thread->id = version | (slot_num & THREAD_ID_SLOT_MASK);
107}
108
109static struct thread_entry * find_empty_thread_slot(void)
110{
111 struct thread_entry *thread = NULL;
112 int n;
113
114 for (n = 0; n < MAXTHREADS; n++)
115 {
116 int state = threads[n].state;
117
118 if (state == STATE_KILLED)
119 {
120 thread = &threads[n];
121 break;
122 }
123 }
124
125 return thread;
126}
127
96/* Do main thread creation in this file scope to avoid the need to double- 128/* Do main thread creation in this file scope to avoid the need to double-
97 return to a prior call-level which would be unaware of the fact setjmp 129 return to a prior call-level which would be unaware of the fact setjmp
98 was used */ 130 was used */
@@ -119,6 +151,8 @@ static int thread_sdl_app_main(void *param)
119bool thread_sdl_init(void *param) 151bool thread_sdl_init(void *param)
120{ 152{
121 struct thread_entry *thread; 153 struct thread_entry *thread;
154 int n;
155
122 memset(cores, 0, sizeof(cores)); 156 memset(cores, 0, sizeof(cores));
123 memset(threads, 0, sizeof(threads)); 157 memset(threads, 0, sizeof(threads));
124 158
@@ -130,6 +164,10 @@ bool thread_sdl_init(void *param)
130 return false; 164 return false;
131 } 165 }
132 166
167 /* Initialize all IDs */
168 for (n = 0; n < MAXTHREADS; n++)
169 threads[n].id = THREAD_ID_INIT(n);
170
133 /* Slot 0 is reserved for the main thread - initialize it here and 171 /* Slot 0 is reserved for the main thread - initialize it here and
134 then create the SDL thread - it is possible to have a quick, early 172 then create the SDL thread - it is possible to have a quick, early
135 shutdown try to access the structure. */ 173 shutdown try to access the structure. */
@@ -179,23 +217,11 @@ void * thread_sdl_thread_unlock(void)
179 return current; 217 return current;
180} 218}
181 219
182static struct thread_entry * find_empty_thread_slot(void) 220struct thread_entry * thread_id_entry(unsigned int thread_id)
183{ 221{
184 struct thread_entry *thread = NULL; 222 return (thread_id == THREAD_ID_CURRENT) ?
185 int n; 223 cores[CURRENT_CORE].running :
186 224 &threads[thread_id & THREAD_ID_SLOT_MASK];
187 for (n = 0; n < MAXTHREADS; n++)
188 {
189 int state = threads[n].state;
190
191 if (state == STATE_KILLED)
192 {
193 thread = &threads[n];
194 break;
195 }
196 }
197
198 return thread;
199} 225}
200 226
201static void add_to_list_l(struct thread_entry **list, 227static void add_to_list_l(struct thread_entry **list,
@@ -239,9 +265,9 @@ static void remove_from_list_l(struct thread_entry **list,
239 thread->l.next->l.prev = thread->l.prev; 265 thread->l.next->l.prev = thread->l.prev;
240} 266}
241 267
242struct thread_entry *thread_get_current(void) 268unsigned int thread_get_current(void)
243{ 269{
244 return cores[CURRENT_CORE].running; 270 return cores[CURRENT_CORE].running->id;
245} 271}
246 272
247void switch_thread(void) 273void switch_thread(void)
@@ -389,9 +415,11 @@ unsigned int thread_queue_wake(struct thread_entry **list)
389 return result; 415 return result;
390} 416}
391 417
392void thread_thaw(struct thread_entry *thread) 418void thread_thaw(unsigned int thread_id)
393{ 419{
394 if (thread->state == STATE_FROZEN) 420 struct thread_entry *thread = thread_id_entry(thread_id);
421
422 if (thread->id == thread_id && thread->state == STATE_FROZEN)
395 { 423 {
396 thread->state = STATE_RUNNING; 424 thread->state = STATE_RUNNING;
397 SDL_SemPost(thread->context.s); 425 SDL_SemPost(thread->context.s);
@@ -441,9 +469,9 @@ int runthread(void *data)
441 return 0; 469 return 0;
442} 470}
443 471
444struct thread_entry* 472unsigned int create_thread(void (*function)(void),
445 create_thread(void (*function)(void), void* stack, size_t stack_size, 473 void* stack, size_t stack_size,
446 unsigned flags, const char *name) 474 unsigned flags, const char *name)
447{ 475{
448 struct thread_entry *thread; 476 struct thread_entry *thread;
449 SDL_Thread* t; 477 SDL_Thread* t;
@@ -455,14 +483,14 @@ struct thread_entry*
455 if (thread == NULL) 483 if (thread == NULL)
456 { 484 {
457 DEBUGF("Failed to find thread slot\n"); 485 DEBUGF("Failed to find thread slot\n");
458 return NULL; 486 return 0;
459 } 487 }
460 488
461 s = SDL_CreateSemaphore(0); 489 s = SDL_CreateSemaphore(0);
462 if (s == NULL) 490 if (s == NULL)
463 { 491 {
464 DEBUGF("Failed to create semaphore\n"); 492 DEBUGF("Failed to create semaphore\n");
465 return NULL; 493 return 0;
466 } 494 }
467 495
468 t = SDL_CreateThread(runthread, thread); 496 t = SDL_CreateThread(runthread, thread);
@@ -470,7 +498,7 @@ struct thread_entry*
470 { 498 {
471 DEBUGF("Failed to create SDL thread\n"); 499 DEBUGF("Failed to create SDL thread\n");
472 SDL_DestroySemaphore(s); 500 SDL_DestroySemaphore(s);
473 return NULL; 501 return 0;
474 } 502 }
475 503
476 thread->stack = stack; 504 thread->stack = stack;
@@ -485,7 +513,7 @@ struct thread_entry*
485 THREAD_SDL_DEBUGF("New Thread: %d (%s)\n", 513 THREAD_SDL_DEBUGF("New Thread: %d (%s)\n",
486 thread - threads, THREAD_SDL_GET_NAME(thread)); 514 thread - threads, THREAD_SDL_GET_NAME(thread));
487 515
488 return thread; 516 return thread->id;
489} 517}
490 518
491void init_threads(void) 519void init_threads(void)
@@ -501,18 +529,22 @@ void init_threads(void)
501 0, THREAD_SDL_GET_NAME(&threads[0])); 529 0, THREAD_SDL_GET_NAME(&threads[0]));
502} 530}
503 531
504void remove_thread(struct thread_entry *thread) 532#ifndef ALLOW_REMOVE_THREAD
533static void remove_thread(unsigned int thread_id)
534#else
535void remove_thread(unsigned int thread_id)
536#endif
505{ 537{
506 struct thread_entry *current = cores[CURRENT_CORE].running; 538 struct thread_entry *current = cores[CURRENT_CORE].running;
539 struct thread_entry *thread = thread_id_entry(thread_id);
540
507 SDL_Thread *t; 541 SDL_Thread *t;
508 SDL_sem *s; 542 SDL_sem *s;
509 543
510 int oldlevel = disable_irq_save(); 544 if (thread_id != THREAD_ID_CURRENT && thread->id != thread_id)
545 return;
511 546
512 if (thread == NULL) 547 int oldlevel = disable_irq_save();
513 {
514 thread = current;
515 }
516 548
517 t = thread->context.t; 549 t = thread->context.t;
518 s = thread->context.s; 550 s = thread->context.s;
@@ -540,6 +572,7 @@ void remove_thread(struct thread_entry *thread)
540 THREAD_SDL_DEBUGF("Removing thread: %d (%s)\n", 572 THREAD_SDL_DEBUGF("Removing thread: %d (%s)\n",
541 thread - threads, THREAD_SDL_GET_NAME(thread)); 573 thread - threads, THREAD_SDL_GET_NAME(thread));
542 574
575 new_thread_id(thread->id, thread);
543 thread->state = STATE_KILLED; 576 thread->state = STATE_KILLED;
544 thread_queue_wake(&thread->queue); 577 thread_queue_wake(&thread->queue);
545 578
@@ -559,17 +592,16 @@ void remove_thread(struct thread_entry *thread)
559 592
560void thread_exit(void) 593void thread_exit(void)
561{ 594{
562 remove_thread(NULL); 595 remove_thread(THREAD_ID_CURRENT);
563} 596}
564 597
565void thread_wait(struct thread_entry *thread) 598void thread_wait(unsigned int thread_id)
566{ 599{
567 struct thread_entry *current = cores[CURRENT_CORE].running; 600 struct thread_entry *current = cores[CURRENT_CORE].running;
601 struct thread_entry *thread = thread_id_entry(thread_id);
568 602
569 if (thread == NULL) 603 if (thread_id == THREAD_ID_CURRENT ||
570 thread = current; 604 (thread->id == thread_id && thread->state != STATE_KILLED))
571
572 if (thread->state != STATE_KILLED)
573 { 605 {
574 current->bqp = &thread->queue; 606 current->bqp = &thread->queue;
575 block_thread(current); 607 block_thread(current);
@@ -583,11 +615,6 @@ int thread_stack_usage(const struct thread_entry *thread)
583 (void)thread; 615 (void)thread;
584} 616}
585 617
586unsigned thread_get_status(const struct thread_entry *thread)
587{
588 return thread->state;
589}
590
591/* Return name if one or ID if none */ 618/* Return name if one or ID if none */
592void thread_get_name(char *buffer, int size, 619void thread_get_name(char *buffer, int size,
593 struct thread_entry *thread) 620 struct thread_entry *thread)