diff options
Diffstat (limited to 'uisimulator/sdl/thread-sdl.c')
-rw-r--r-- | uisimulator/sdl/thread-sdl.c | 34 |
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 */ |
50 | struct core_entry cores[NUM_CORES]; | ||
49 | struct thread_entry threads[MAXTHREADS]; | 51 | struct 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 | ||
157 | void thread_sdl_lock(void) | ||
158 | { | ||
159 | SDL_LockMutex(m); | ||
160 | } | ||
161 | |||
162 | void thread_sdl_unlock(void) | ||
163 | { | ||
164 | SDL_UnlockMutex(m); | ||
165 | } | ||
166 | |||
167 | static int find_empty_thread_slot(void) | 160 | static 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 | ||
216 | static 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 | |||
223 | struct thread_entry *thread_get_current(void) | 227 | struct 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 | ||
495 | void thread_wait(struct thread_entry *thread) | 507 | void thread_wait(struct thread_entry *thread) |