summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-12-03 14:01:12 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-12-03 14:01:12 +0000
commita4d19b7e899a9223433fcb91627af737a638e9d3 (patch)
treec3ca7e9782f7029ca0226969c1e402f20d4fa444
parent08533e7f37f9bd97a5653b137a179111f37d63f6 (diff)
downloadrockbox-a4d19b7e899a9223433fcb91627af737a638e9d3.tar.gz
rockbox-a4d19b7e899a9223433fcb91627af737a638e9d3.zip
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
-rw-r--r--uisimulator/common/io.c127
-rw-r--r--uisimulator/sdl/thread-sdl.c17
-rw-r--r--uisimulator/sdl/thread-sdl.h2
-rw-r--r--uisimulator/sdl/uisdl.c6
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 @@
55#include "debug.h" 55#include "debug.h"
56#include "config.h" 56#include "config.h"
57#include "ata.h" /* for IF_MV2 et al. */ 57#include "ata.h" /* for IF_MV2 et al. */
58#include "thread-sdl.h"
59
58 60
59/* Windows (and potentially other OSes) distinguish binary and text files. 61/* Windows (and potentially other OSes) distinguish binary and text files.
60 * Define a dummy for the others. */ 62 * Define a dummy for the others. */
@@ -189,95 +191,22 @@ static unsigned int rockbox2sim(int opt)
189/** Simulator I/O engine routines **/ 191/** Simulator I/O engine routines **/
190enum 192enum
191{ 193{
192 IO_QUIT = -1,
193 IO_OPEN,
194 IO_CLOSE,
195 IO_READ, 194 IO_READ,
196 IO_WRITE, 195 IO_WRITE,
197}; 196};
198 197
199struct sim_io 198struct sim_io
200{ 199{
201 SDL_mutex *m; /* Mutex for condition */
202 SDL_cond *c; /* Condition for synchronizing threads */
203 SDL_Thread *t; /* The I/O thread */
204 struct mutex sim_mutex; /* Rockbox mutex */ 200 struct mutex sim_mutex; /* Rockbox mutex */
205 volatile int cmd; /* The command to perform */ 201 volatile int cmd; /* The command to perform */
206 volatile int ready; /* I/O ready flag - 1= ready */ 202 volatile int ready; /* I/O ready flag - 1= ready */
207 volatile int fd; /* The file to read/write */ 203 volatile int fd; /* The file to read/write */
208 void* volatile buf; /* The buffer to read/write */ 204 void* volatile buf; /* The buffer to read/write */
209 volatile size_t count; /* Number of bytes to read/write */ 205 volatile size_t count; /* Number of bytes to read/write */
210 ssize_t result; /* Result of operation */
211}; 206};
212 207
213static struct sim_io io; 208static struct sim_io io;
214 209
215static int io_thread(void *data)
216{
217 SDL_LockMutex(io.m);
218
219 io.ready = 1; /* Indication mutex has been locked */
220
221 for (;;)
222 {
223 SDL_CondWait(io.c, io.m); /* unlock mutex and wait */
224
225 switch (io.cmd)
226 {
227 case IO_READ:
228 io.result = read(io.fd, io.buf, io.count);
229 io.ready = 1;
230 break;
231 case IO_WRITE:
232 io.result = write(io.fd, io.buf, io.count);
233 io.ready = 1;
234 break;
235 case IO_QUIT:
236 SDL_UnlockMutex(io.m);
237 return 0;
238 }
239 }
240
241 (void)data;
242}
243
244bool sim_io_init(void)
245{
246 io.ready = 0;
247
248 io.m = SDL_CreateMutex();
249 if (io.m == NULL)
250 {
251 fprintf(stderr, "Failed to create IO mutex\n");
252 return false;
253 }
254
255 io.c = SDL_CreateCond();
256 if (io.c == NULL)
257 {
258 fprintf(stderr, "Failed to create IO cond\n");
259 return false;
260 }
261
262 io.t = SDL_CreateThread(io_thread, NULL);
263 if (io.t == NULL)
264 {
265 fprintf(stderr, "Failed to create IO thread\n");
266 return false;
267 }
268
269 /* Wait for IO thread to lock mutex */
270 while (!io.ready)
271 SDL_Delay(0);
272
273 /* Wait for it to unlock */
274 SDL_LockMutex(io.m);
275 /* Free it for another thread */
276 SDL_UnlockMutex(io.m);
277
278 return true;
279}
280
281int ata_init(void) 210int ata_init(void)
282{ 211{
283 /* Initialize the rockbox kernel objects on a rockbox thread */ 212 /* Initialize the rockbox kernel objects on a rockbox thread */
@@ -285,38 +214,28 @@ int ata_init(void)
285 return 1; 214 return 1;
286} 215}
287 216
288void sim_io_shutdown(void) 217static ssize_t io_trigger_and_wait(int cmd)
289{
290 SDL_LockMutex(io.m);
291
292 io.cmd = IO_QUIT;
293
294 SDL_CondSignal(io.c);
295 SDL_UnlockMutex(io.m);
296
297 SDL_WaitThread(io.t, NULL);
298
299 SDL_DestroyMutex(io.m);
300 SDL_DestroyCond(io.c);
301}
302
303static void io_trigger_and_wait(int cmd)
304{ 218{
305 /* Lock mutex before setting up new params and signaling condition */ 219 void *mythread;
306 SDL_LockMutex(io.m); 220 ssize_t result;
307 221
308 io.cmd = cmd; 222 /* Allow other rockbox threads to run */
309 io.ready = 0; 223 mythread = thread_sdl_thread_unlock();
310 224
311 /* Get thread started */ 225 switch (cmd)
312 SDL_CondSignal(io.c); 226 {
227 case IO_READ:
228 result = read(io.fd, io.buf, io.count);
229 break;
230 case IO_WRITE:
231 result = write(io.fd, io.buf, io.count);
232 break;
233 }
313 234
314 /* Let it run */ 235 /* Regain our status as current */
315 SDL_UnlockMutex(io.m); 236 thread_sdl_thread_lock(mythread);
316 237
317 /* Wait for IO to complete */ 238 return result;
318 while (!io.ready)
319 yield();
320} 239}
321 240
322static const char *get_sim_rootdir() 241static const char *get_sim_rootdir()
@@ -470,9 +389,7 @@ ssize_t sim_read(int fd, void *buf, size_t count)
470 io.buf = buf; 389 io.buf = buf;
471 io.count = count; 390 io.count = count;
472 391
473 io_trigger_and_wait(IO_READ); 392 result = io_trigger_and_wait(IO_READ);
474
475 result = io.result;
476 393
477 mutex_unlock(&io.sim_mutex); 394 mutex_unlock(&io.sim_mutex);
478 395
@@ -489,9 +406,7 @@ ssize_t sim_write(int fd, const void *buf, size_t count)
489 io.buf = (void*)buf; 406 io.buf = (void*)buf;
490 io.count = count; 407 io.count = count;
491 408
492 io_trigger_and_wait(IO_WRITE); 409 result = io_trigger_and_wait(IO_WRITE);
493
494 result = io.result;
495 410
496 mutex_unlock(&io.sim_mutex); 411 mutex_unlock(&io.sim_mutex);
497 412
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)
157 return true; 157 return true;
158} 158}
159 159
160/* A way to yield and leave the threading system for extended periods */
161void thread_sdl_thread_lock(void *me)
162{
163 SDL_LockMutex(m);
164 running = (struct thread_entry *)me;
165
166 if (threads_exit)
167 remove_thread(NULL);
168}
169
170void * thread_sdl_thread_unlock(void)
171{
172 struct thread_entry *current = running;
173 SDL_UnlockMutex(m);
174 return current;
175}
176
160static int find_empty_thread_slot(void) 177static int find_empty_thread_slot(void)
161{ 178{
162 int n; 179 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 @@
23#include "SDL_thread.h" 23#include "SDL_thread.h"
24 24
25extern SDL_Thread *gui_thread; /* The "main" thread */ 25extern SDL_Thread *gui_thread; /* The "main" thread */
26void thread_sdl_thread_lock(void *me);
27void * thread_sdl_thread_unlock(void);
26bool thread_sdl_init(void *param); /* Init the sim threading API - thread created calls app_main */ 28bool thread_sdl_init(void *param); /* Init the sim threading API - thread created calls app_main */
27void thread_sdl_shutdown(void); /* Shut down all kernel threads gracefully */ 29void thread_sdl_shutdown(void); /* Shut down all kernel threads gracefully */
28void thread_sdl_lock(void); /* Sync with SDL threads */ 30void 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)
192 sync primitives by kernel threads */ 192 sync primitives by kernel threads */
193 thread_sdl_shutdown(); 193 thread_sdl_shutdown();
194 SDL_RemoveTimer(tick_timer_id); 194 SDL_RemoveTimer(tick_timer_id);
195 sim_io_shutdown();
196 sim_kernel_shutdown(); 195 sim_kernel_shutdown();
197 return true; 196 return true;
198} 197}
@@ -277,11 +276,6 @@ int main(int argc, char *argv[])
277 return -1; 276 return -1;
278 } 277 }
279 278
280 if (!sim_io_init()) {
281 fprintf(stderr, "sim_io_init failed\n");
282 return -1;
283 }
284
285 if (!gui_startup()) { 279 if (!gui_startup()) {
286 fprintf(stderr, "gui_startup failed\n"); 280 fprintf(stderr, "gui_startup failed\n");
287 return -1; 281 return -1;