From a4d19b7e899a9223433fcb91627af737a638e9d3 Mon Sep 17 00:00:00 2001 From: Michael Sevakis Date: Mon, 3 Dec 2007 14:01:12 +0000 Subject: Simplify the uisimulator I/O routine and let the rockbox thread calling the functions be the background thread. Should speed things up too and lose none of the advantanges of background I/O. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15870 a1c6a512-1295-4272-9138-f99709370657 --- uisimulator/common/io.c | 127 +++++++------------------------------------ uisimulator/sdl/thread-sdl.c | 17 ++++++ uisimulator/sdl/thread-sdl.h | 2 + uisimulator/sdl/uisdl.c | 6 -- 4 files changed, 40 insertions(+), 112 deletions(-) diff --git a/uisimulator/common/io.c b/uisimulator/common/io.c index 4e202228a8..62d869f3fc 100644 --- a/uisimulator/common/io.c +++ b/uisimulator/common/io.c @@ -55,6 +55,8 @@ #include "debug.h" #include "config.h" #include "ata.h" /* for IF_MV2 et al. */ +#include "thread-sdl.h" + /* Windows (and potentially other OSes) distinguish binary and text files. * Define a dummy for the others. */ @@ -189,95 +191,22 @@ static unsigned int rockbox2sim(int opt) /** Simulator I/O engine routines **/ enum { - IO_QUIT = -1, - IO_OPEN, - IO_CLOSE, IO_READ, IO_WRITE, }; struct sim_io { - SDL_mutex *m; /* Mutex for condition */ - SDL_cond *c; /* Condition for synchronizing threads */ - SDL_Thread *t; /* The I/O thread */ struct mutex sim_mutex; /* Rockbox mutex */ volatile int cmd; /* The command to perform */ volatile int ready; /* I/O ready flag - 1= ready */ volatile int fd; /* The file to read/write */ void* volatile buf; /* The buffer to read/write */ volatile size_t count; /* Number of bytes to read/write */ - ssize_t result; /* Result of operation */ }; static struct sim_io io; -static int io_thread(void *data) -{ - SDL_LockMutex(io.m); - - io.ready = 1; /* Indication mutex has been locked */ - - for (;;) - { - SDL_CondWait(io.c, io.m); /* unlock mutex and wait */ - - switch (io.cmd) - { - case IO_READ: - io.result = read(io.fd, io.buf, io.count); - io.ready = 1; - break; - case IO_WRITE: - io.result = write(io.fd, io.buf, io.count); - io.ready = 1; - break; - case IO_QUIT: - SDL_UnlockMutex(io.m); - return 0; - } - } - - (void)data; -} - -bool sim_io_init(void) -{ - io.ready = 0; - - io.m = SDL_CreateMutex(); - if (io.m == NULL) - { - fprintf(stderr, "Failed to create IO mutex\n"); - return false; - } - - io.c = SDL_CreateCond(); - if (io.c == NULL) - { - fprintf(stderr, "Failed to create IO cond\n"); - return false; - } - - io.t = SDL_CreateThread(io_thread, NULL); - if (io.t == NULL) - { - fprintf(stderr, "Failed to create IO thread\n"); - return false; - } - - /* Wait for IO thread to lock mutex */ - while (!io.ready) - SDL_Delay(0); - - /* Wait for it to unlock */ - SDL_LockMutex(io.m); - /* Free it for another thread */ - SDL_UnlockMutex(io.m); - - return true; -} - int ata_init(void) { /* Initialize the rockbox kernel objects on a rockbox thread */ @@ -285,38 +214,28 @@ int ata_init(void) return 1; } -void sim_io_shutdown(void) -{ - SDL_LockMutex(io.m); - - io.cmd = IO_QUIT; - - SDL_CondSignal(io.c); - SDL_UnlockMutex(io.m); - - SDL_WaitThread(io.t, NULL); - - SDL_DestroyMutex(io.m); - SDL_DestroyCond(io.c); -} - -static void io_trigger_and_wait(int cmd) +static ssize_t io_trigger_and_wait(int cmd) { - /* Lock mutex before setting up new params and signaling condition */ - SDL_LockMutex(io.m); + void *mythread; + ssize_t result; - io.cmd = cmd; - io.ready = 0; + /* Allow other rockbox threads to run */ + mythread = thread_sdl_thread_unlock(); - /* Get thread started */ - SDL_CondSignal(io.c); + switch (cmd) + { + case IO_READ: + result = read(io.fd, io.buf, io.count); + break; + case IO_WRITE: + result = write(io.fd, io.buf, io.count); + break; + } - /* Let it run */ - SDL_UnlockMutex(io.m); + /* Regain our status as current */ + thread_sdl_thread_lock(mythread); - /* Wait for IO to complete */ - while (!io.ready) - yield(); + return result; } static const char *get_sim_rootdir() @@ -470,9 +389,7 @@ ssize_t sim_read(int fd, void *buf, size_t count) io.buf = buf; io.count = count; - io_trigger_and_wait(IO_READ); - - result = io.result; + result = io_trigger_and_wait(IO_READ); mutex_unlock(&io.sim_mutex); @@ -489,9 +406,7 @@ ssize_t sim_write(int fd, const void *buf, size_t count) io.buf = (void*)buf; io.count = count; - io_trigger_and_wait(IO_WRITE); - - result = io.result; + result = io_trigger_and_wait(IO_WRITE); mutex_unlock(&io.sim_mutex); diff --git a/uisimulator/sdl/thread-sdl.c b/uisimulator/sdl/thread-sdl.c index a07ac29738..b8297072f2 100644 --- a/uisimulator/sdl/thread-sdl.c +++ b/uisimulator/sdl/thread-sdl.c @@ -157,6 +157,23 @@ bool thread_sdl_init(void *param) return true; } +/* A way to yield and leave the threading system for extended periods */ +void thread_sdl_thread_lock(void *me) +{ + SDL_LockMutex(m); + running = (struct thread_entry *)me; + + if (threads_exit) + remove_thread(NULL); +} + +void * thread_sdl_thread_unlock(void) +{ + struct thread_entry *current = running; + SDL_UnlockMutex(m); + return current; +} + static int find_empty_thread_slot(void) { int n; diff --git a/uisimulator/sdl/thread-sdl.h b/uisimulator/sdl/thread-sdl.h index 3739130f97..0f3b7b6d3a 100644 --- a/uisimulator/sdl/thread-sdl.h +++ b/uisimulator/sdl/thread-sdl.h @@ -23,6 +23,8 @@ #include "SDL_thread.h" extern SDL_Thread *gui_thread; /* The "main" thread */ +void thread_sdl_thread_lock(void *me); +void * thread_sdl_thread_unlock(void); bool thread_sdl_init(void *param); /* Init the sim threading API - thread created calls app_main */ void thread_sdl_shutdown(void); /* Shut down all kernel threads gracefully */ void thread_sdl_lock(void); /* Sync with SDL threads */ diff --git a/uisimulator/sdl/uisdl.c b/uisimulator/sdl/uisdl.c index de6089b648..e0a449ed48 100644 --- a/uisimulator/sdl/uisdl.c +++ b/uisimulator/sdl/uisdl.c @@ -192,7 +192,6 @@ bool gui_shutdown(void) sync primitives by kernel threads */ thread_sdl_shutdown(); SDL_RemoveTimer(tick_timer_id); - sim_io_shutdown(); sim_kernel_shutdown(); return true; } @@ -277,11 +276,6 @@ int main(int argc, char *argv[]) return -1; } - if (!sim_io_init()) { - fprintf(stderr, "sim_io_init failed\n"); - return -1; - } - if (!gui_startup()) { fprintf(stderr, "gui_startup failed\n"); return -1; -- cgit v1.2.3