From f4bdf56bfdca7bc37d23cc695f8c4b7235f44e84 Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Wed, 14 Apr 2010 11:25:11 +0200 Subject: [PATCH] General cleanup and comment corrections. --- uisimulator/common/thread-pth.c | 96 ++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 55 deletions(-) diff --git a/uisimulator/common/thread-pth.c b/uisimulator/common/thread-pth.c index 6d6c057dc..fd220f0ed 100644 --- a/uisimulator/common/thread-pth.c +++ b/uisimulator/common/thread-pth.c @@ -20,22 +20,20 @@ ****************************************************************************/ #include -#include #include #include #include #include -#include #include #include "system.h" #include "kernel.h" #include "system-sdl.h" #include "thread.h" #include "debug.h" -#include "SDL.h" +#include /* Define this as 1 to show informational messages that are not errors. */ -#define THREAD_SDL_DEBUGF_ENABLED 1 +#define THREAD_SDL_DEBUGF_ENABLED 0 #if THREAD_SDL_DEBUGF_ENABLED #define THREAD_SDL_DEBUGF(...) DEBUGF(__VA_ARGS__) @@ -62,9 +60,6 @@ struct thread_entry * my_thread = NULL; static int wakeup_pth_thread(void* data) { -/* - THREAD_SDL_DEBUGF("Waking up thread; %p\n", data); -*/ struct thread_entry *t = (struct thread_entry*)data; return (t->state == STATE_RUNNING); } @@ -72,10 +67,10 @@ static int wakeup_pth_thread(void* data) void thread_pth_shutdown(void) { int i; - /* Tell all threads jump back to their start routines, unlock and exit - gracefully - we'll check each one in turn for it's status. Threads - _could_ terminate via remove_thread or multiple threads could exit - on each unlock but that is safe. */ + /* wait for all threads to exit gracefully - pth_exit() is called + * during pth_join() + * pth_exit() goes back in the call stack to return in thread's entry + * routine and then runthread() */ /* Do this before trying to acquire lock */ threads_exit = true; @@ -89,7 +84,7 @@ void thread_pth_shutdown(void) pth_t t = thread->context.t; if (t) { - /* Signal thread on delay or block */ + /* force thread runnable */ thread->state = STATE_RUNNING; /* Wait for it to finish */ THREAD_SDL_DEBUGF("Waiting for (%s) to finish\n", @@ -133,11 +128,12 @@ static struct thread_entry * find_empty_thread_slot(void) return thread; } -/* Do main thread creation in this file scope to avoid the need to double- - return to a prior call-level which would be unaware of the fact setjmp - was used */ +/* + * entry point for the app_main thread from main.c */ extern void app_main(void); +/* + * Wrap entering the thread's entry point for easier exiting */ static void* runthread(void *thread) { struct thread_entry *current; @@ -155,16 +151,18 @@ static void* runthread(void *thread) return NULL; } -void dump_threads(int sig) +static void dump_threads(int sig) { - (void)sig; - //if (sig == SIGSEGV) + pth_ctrl(PTH_CTRL_DUMPSTATE, stderr); + switch (sig) { - pth_ctrl(PTH_CTRL_DUMPSTATE, stderr); -/* - if (sig == SIGTERM) -*/ - exit(0); + case SIGABRT: + case SIGTERM: + case SIGKILL: + case SIGSEGV: + exit(-2); + default: + break; } } @@ -178,6 +176,13 @@ void thread_wait(unsigned int id) pth_wait(ev); } +/* + * kill all threads if we exit out of order */ +static void atexit_handler(void) +{ + pth_kill(); +} + /* Initialize threading */ bool thread_pth_init(void *param) { @@ -187,25 +192,23 @@ bool thread_pth_init(void *param) memset(cores, 0, sizeof(cores)); memset(threads, 0, sizeof(threads)); - signal(SIGSEGV, dump_threads); - signal(SIGTERM, dump_threads); - signal(SIGKILL, dump_threads); - signal(SIGINT, dump_threads); /* Initialize all IDs */ for (i = 0; i < MAXTHREADS; i++) threads[i].id = THREAD_ID_INIT(i); if (pth_init() != true) { - fprintf(stderr, "Failed to initialize pth threads\n"); + THREAD_PANICF("Failed to initialize pth threads\n"); return false; } + signal(SIGSEGV, dump_threads); + signal(SIGABRT, dump_threads); + atexit(atexit_handler); /* * pth wants the stack on the heap and create_thread malloc's one * we don't need to pass one */ i = create_thread(app_main, NULL, stack_size, 0, "app_main"); - /* our semaphore will wait until the message is posted */ cores[CURRENT_CORE].running = thread_id_entry(i); THREAD_SDL_DEBUGF("Main thread: %p\n", thread_id_entry(i)); @@ -222,9 +225,10 @@ void thread_pth_exception_wait(void) } } -/* A way to yield and leave the threading system for extended periods */ +/* not applicable under cooperative threading */ void thread_pth_thread_lock(void *me) { + (void)me; if (threads_exit) thread_exit(); } @@ -304,9 +308,6 @@ void switch_thread(void) case STATE_BLOCKED: { int oldlevel; -/* - THREAD_SDL_DEBUGF("Register Wakeup callback for thread: %p\n", current); -*/ pth_event_t ev = pth_event(PTH_EVENT_FUNC, wakeup_pth_thread, current, pth_time(0, 1000)); /* wait for something being posted on the event */ @@ -322,10 +323,6 @@ void switch_thread(void) int oldlevel; long usecs = current->tmo_tick; long secs = usecs / 1000000; - double last_time; -/* - THREAD_SDL_DEBUGF("Register Wakeup callback for thread: %p\n", current); -*/ /* create the message event as for BLOCKED */ pth_event_t msg_ev = pth_event(PTH_EVENT_FUNC, wakeup_pth_thread, current, pth_time(0, 1000)); @@ -333,15 +330,10 @@ void switch_thread(void) pth_event_t time_ev = pth_event(PTH_EVENT_TIME, pth_timeout(secs, usecs % 1000000)); - if (current == my_thread) - THREAD_SDL_DEBUGF("Thread %s shall wait: %ld.%lds\n", current->name, secs, usecs % 1000000); /* wait for either event to fire first */ pth_event_t ring = pth_event_concat(msg_ev, time_ev, NULL); - last_time = SDL_GetTicks(); pth_wait(ring); - if (current == my_thread) - THREAD_SDL_DEBUGF("Thread %s waited %lf ms\n", current->name, SDL_GetTicks() - last_time); pth_event_free(ring, PTH_FREE_ALL); oldlevel = disable_irq_save(); @@ -383,6 +375,7 @@ void sleep_thread(int ticks) current->state = STATE_SLEEPING; + /* add a reminder for more accurate sleeps */ rem = (SDL_GetTicks() - start_tick) % (1000/HZ); if (rem < 0) rem = 0; @@ -415,8 +408,6 @@ unsigned int wakeup_thread(struct thread_entry **list) case STATE_BLOCKED_W_TMO: remove_from_list_l(list, thread); thread->state = STATE_RUNNING; - if (thread == my_thread) - THREAD_SDL_DEBUGF("Waking %s up\n", thread->name); /* post the message to wake it up */ return THREAD_OK; } @@ -482,7 +473,7 @@ unsigned int create_thread(void (*function)(void), if (stack == NULL) { - DEBUGF("Out of memory\n"); + THREAD_PANICF("%s(): Out of memory\n", __func__); return 0; } @@ -497,10 +488,8 @@ unsigned int create_thread(void (*function)(void), } attr = pth_attr_new(); - pth_attr_set(attr, PTH_ATTR_NAME, strdup(name)); - /* Rockbox threads usually never return so don't try to join them - * instead, we exit them through longjmps to get them out of their - * infinite main loop */ + pth_attr_set(attr, PTH_ATTR_NAME, name); + /* explicitely set joinable we do need it for sane exiting */ pth_attr_set(attr, PTH_ATTR_JOINABLE, true); pth_attr_set(attr, PTH_ATTR_STACK_ADDR, stack); pth_attr_set(attr, PTH_ATTR_STACK_SIZE, stack_size); @@ -603,14 +592,11 @@ void remove_thread(unsigned int thread_id) if (thread == current) { - /* Do a graceful exit - perform the longjmp back into the thread - function to return */ + /* Do a graceful exit */ restore_irq(oldlevel); - /* jump back to runthread() where we simply return */ + /* terminate the current thread - it works by returning in the + * threads entry function */ pth_exit(NULL); -/* - longjmp(thread_jmpbufs[current - threads], 1); -*/ return; } -- 2.11.4.GIT