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.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/uisimulator/sdl/thread-sdl.c b/uisimulator/sdl/thread-sdl.c
index 6a3c4af9eb..a07ac29738 100644
--- a/uisimulator/sdl/thread-sdl.c
+++ b/uisimulator/sdl/thread-sdl.c
@@ -24,6 +24,7 @@
24#include <stdlib.h> 24#include <stdlib.h>
25#include <memory.h> 25#include <memory.h>
26#include <setjmp.h> 26#include <setjmp.h>
27#include "system-sdl.h"
27#include "thread-sdl.h" 28#include "thread-sdl.h"
28#include "kernel.h" 29#include "kernel.h"
29#include "thread.h" 30#include "thread.h"
@@ -45,7 +46,8 @@ static char __name[32];
45#define THREAD_PANICF(str...) \ 46#define THREAD_PANICF(str...) \
46 ({ fprintf(stderr, str); exit(-1); }) 47 ({ fprintf(stderr, str); exit(-1); })
47 48
48/* Thread entries as in core */ 49/* Thread/core entries as in rockbox core */
50struct core_entry cores[NUM_CORES];
49struct thread_entry threads[MAXTHREADS]; 51struct thread_entry threads[MAXTHREADS];
50/* Jump buffers for graceful exit - kernel threads don't stay neatly 52/* Jump buffers for graceful exit - kernel threads don't stay neatly
51 * in their start routines responding to messages so this is the only 53 * in their start routines responding to messages so this is the only
@@ -133,6 +135,7 @@ bool thread_sdl_init(void *param)
133 running->name = "main"; 135 running->name = "main";
134 running->state = STATE_RUNNING; 136 running->state = STATE_RUNNING;
135 running->context.c = SDL_CreateCond(); 137 running->context.c = SDL_CreateCond();
138 cores[CURRENT_CORE].irq_level = STAY_IRQ_LEVEL;
136 139
137 if (running->context.c == NULL) 140 if (running->context.c == NULL)
138 { 141 {
@@ -154,16 +157,6 @@ bool thread_sdl_init(void *param)
154 return true; 157 return true;
155} 158}
156 159
157void thread_sdl_lock(void)
158{
159 SDL_LockMutex(m);
160}
161
162void thread_sdl_unlock(void)
163{
164 SDL_UnlockMutex(m);
165}
166
167static int find_empty_thread_slot(void) 160static int find_empty_thread_slot(void)
168{ 161{
169 int n; 162 int n;
@@ -220,6 +213,17 @@ static void remove_from_list_l(struct thread_entry **list,
220 thread->l.next->l.prev = thread->l.prev; 213 thread->l.next->l.prev = thread->l.prev;
221} 214}
222 215
216static void run_blocking_ops(void)
217{
218 int level = cores[CURRENT_CORE].irq_level;
219
220 if (level != STAY_IRQ_LEVEL)
221 {
222 cores[CURRENT_CORE].irq_level = STAY_IRQ_LEVEL;
223 set_irq_level(level);
224 }
225}
226
223struct thread_entry *thread_get_current(void) 227struct thread_entry *thread_get_current(void)
224{ 228{
225 return running; 229 return running;
@@ -373,6 +377,8 @@ void _block_thread(struct thread_queue *tq)
373 thread->bqp = tq; 377 thread->bqp = tq;
374 add_to_list_l(&tq->queue, thread); 378 add_to_list_l(&tq->queue, thread);
375 379
380 run_blocking_ops();
381
376 SDL_CondWait(thread->context.c, m); 382 SDL_CondWait(thread->context.c, m);
377 running = thread; 383 running = thread;
378 384
@@ -388,6 +394,8 @@ void block_thread_w_tmo(struct thread_queue *tq, int ticks)
388 thread->bqp = tq; 394 thread->bqp = tq;
389 add_to_list_l(&tq->queue, thread); 395 add_to_list_l(&tq->queue, thread);
390 396
397 run_blocking_ops();
398
391 SDL_CondWaitTimeout(thread->context.c, m, (1000/HZ) * ticks); 399 SDL_CondWaitTimeout(thread->context.c, m, (1000/HZ) * ticks);
392 running = thread; 400 running = thread;
393 401
@@ -451,6 +459,8 @@ void remove_thread(struct thread_entry *thread)
451 SDL_Thread *t; 459 SDL_Thread *t;
452 SDL_cond *c; 460 SDL_cond *c;
453 461
462 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
463
454 if (thread == NULL) 464 if (thread == NULL)
455 { 465 {
456 thread = current; 466 thread = current;
@@ -486,10 +496,12 @@ void remove_thread(struct thread_entry *thread)
486 { 496 {
487 /* Do a graceful exit - perform the longjmp back into the thread 497 /* Do a graceful exit - perform the longjmp back into the thread
488 function to return */ 498 function to return */
499 set_irq_level(oldlevel);
489 longjmp(thread_jmpbufs[current - threads], 1); 500 longjmp(thread_jmpbufs[current - threads], 1);
490 } 501 }
491 502
492 SDL_KillThread(t); 503 SDL_KillThread(t);
504 set_irq_level(oldlevel);
493} 505}
494 506
495void thread_wait(struct thread_entry *thread) 507void thread_wait(struct thread_entry *thread)