1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Michael Sevakis 2007-12-03 14:01:12 +00:00
parent 08533e7f37
commit a4d19b7e89
4 changed files with 40 additions and 112 deletions

View file

@ -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)
static ssize_t io_trigger_and_wait(int cmd)
{
SDL_LockMutex(io.m);
void *mythread;
ssize_t result;
io.cmd = IO_QUIT;
/* Allow other rockbox threads to run */
mythread = thread_sdl_thread_unlock();
SDL_CondSignal(io.c);
SDL_UnlockMutex(io.m);
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;
}
SDL_WaitThread(io.t, NULL);
/* Regain our status as current */
thread_sdl_thread_lock(mythread);
SDL_DestroyMutex(io.m);
SDL_DestroyCond(io.c);
}
static void io_trigger_and_wait(int cmd)
{
/* Lock mutex before setting up new params and signaling condition */
SDL_LockMutex(io.m);
io.cmd = cmd;
io.ready = 0;
/* Get thread started */
SDL_CondSignal(io.c);
/* Let it run */
SDL_UnlockMutex(io.m);
/* 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);

View file

@ -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;

View file

@ -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 */

View file

@ -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;