summaryrefslogtreecommitdiff
path: root/uisimulator/common
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2007-09-08 12:20:53 +0000
committerMichael Sevakis <jethead71@rockbox.org>2007-09-08 12:20:53 +0000
commitf64ebb1c1f10e8d15fcc4879d781703c86c5fb8b (patch)
tree065072709c699ac6dc3eb640368bd3f4106144e4 /uisimulator/common
parent69b4654ea28049c7e8637d521327ba10ae405f8b (diff)
downloadrockbox-f64ebb1c1f10e8d15fcc4879d781703c86c5fb8b.tar.gz
rockbox-f64ebb1c1f10e8d15fcc4879d781703c86c5fb8b.zip
Sim I/O and threading that runs more like on target. Tweakable if any genuine slowness imitation is required for any one of them. One point of concern is the sim shutdown on an OS other than Linux just because terminating threads in a manner other than having the do it themselves is kind of dirty IMHO.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14639 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'uisimulator/common')
-rw-r--r--uisimulator/common/io.c169
1 files changed, 168 insertions, 1 deletions
diff --git a/uisimulator/common/io.c b/uisimulator/common/io.c
index 3f7087876a..127a1c36f1 100644
--- a/uisimulator/common/io.c
+++ b/uisimulator/common/io.c
@@ -47,7 +47,10 @@
47#define MAX_PATH 260 47#define MAX_PATH 260
48 48
49#include <fcntl.h> 49#include <fcntl.h>
50 50#include <SDL.h>
51#include <SDL_thread.h>
52#include "thread.h"
53#include "kernel.h"
51#include "debug.h" 54#include "debug.h"
52#include "config.h" 55#include "config.h"
53 56
@@ -175,6 +178,131 @@ static unsigned int rockbox2sim(int opt)
175} 178}
176#endif 179#endif
177 180
181/** Simulator I/O engine routines **/
182enum
183{
184 IO_QUIT = -1,
185 IO_OPEN,
186 IO_CLOSE,
187 IO_READ,
188 IO_WRITE,
189};
190
191struct sim_io
192{
193 SDL_mutex *m; /* Mutex for condition */
194 SDL_cond *c; /* Condition for synchronizing threads */
195 SDL_Thread *t; /* The I/O thread */
196 struct mutex sim_mutex; /* Rockbox mutex */
197 volatile int cmd; /* The command to perform */
198 volatile int ready; /* I/O ready flag - 1= ready */
199 volatile int fd; /* The file to read/write */
200 void* volatile buf; /* The buffer to read/write */
201 volatile size_t count; /* Number of bytes to read/write */
202 ssize_t result; /* Result of operation */
203};
204
205static struct sim_io io;
206
207static int io_thread(void *data)
208{
209 SDL_LockMutex(io.m);
210
211 io.ready = 1; /* Indication mutex has been locked */
212
213 for (;;)
214 {
215 SDL_CondWait(io.c, io.m); /* unlock mutex and wait */
216
217 switch (io.cmd)
218 {
219 case IO_READ:
220 io.result = read(io.fd, io.buf, io.count);
221 io.ready = 1;
222 break;
223 case IO_WRITE:
224 io.result = write(io.fd, io.buf, io.count);
225 io.ready = 1;
226 break;
227 case IO_QUIT:
228 SDL_UnlockMutex(io.m);
229 return 0;
230 }
231 }
232
233 (void)data;
234}
235
236void sim_io_init(void)
237{
238 mutex_init(&io.sim_mutex);
239
240 io.ready = 0;
241
242 io.m = SDL_CreateMutex();
243 if (io.m == NULL)
244 {
245 fprintf(stderr, "Failed to create IO mutex\n");
246 exit(-1);
247 }
248
249 io.c = SDL_CreateCond();
250 if (io.c == NULL)
251 {
252 fprintf(stderr, "Failed to create IO cond\n");
253 exit(-1);
254 }
255
256 io.t = SDL_CreateThread(io_thread, NULL);
257 if (io.t == NULL)
258 {
259 fprintf(stderr, "Failed to create IO thread\n");
260 exit(-1);
261 }
262
263 /* Wait for IO thread to lock mutex */
264 while (!io.ready);
265
266 /* Wait for it to unlock */
267 SDL_LockMutex(io.m);
268 /* Free it for another thread */
269 SDL_UnlockMutex(io.m);
270}
271
272void sim_io_shutdown(void)
273{
274 SDL_LockMutex(io.m);
275
276 io.cmd = IO_QUIT;
277
278 SDL_CondSignal(io.c);
279 SDL_UnlockMutex(io.m);
280
281 SDL_WaitThread(io.t, NULL);
282
283 SDL_DestroyMutex(io.m);
284 SDL_DestroyCond(io.c);
285}
286
287static void io_trigger_and_wait(int cmd)
288{
289 /* Lock mutex before setting up new params and signaling condition */
290 SDL_LockMutex(io.m);
291
292 io.cmd = cmd;
293 io.ready = 0;
294
295 /* Get thread started */
296 SDL_CondSignal(io.c);
297
298 /* Let it run */
299 SDL_UnlockMutex(io.m);
300
301 /* Wait for IO to complete */
302 while (!io.ready)
303 yield();
304}
305
178MYDIR *sim_opendir(const char *name) 306MYDIR *sim_opendir(const char *name)
179{ 307{
180 char buffer[MAX_PATH]; /* sufficiently big */ 308 char buffer[MAX_PATH]; /* sufficiently big */
@@ -287,6 +415,45 @@ int sim_creat(const char *name)
287#endif 415#endif
288} 416}
289 417
418ssize_t sim_read(int fd, void *buf, size_t count)
419{
420 ssize_t result;
421
422 mutex_lock(&io.sim_mutex);
423
424 /* Setup parameters */
425 io.fd = fd;
426 io.buf = buf;
427 io.count = count;
428
429 io_trigger_and_wait(IO_READ);
430
431 result = io.result;
432
433 mutex_unlock(&io.sim_mutex);
434
435 return result;
436}
437
438ssize_t sim_write(int fd, const void *buf, size_t count)
439{
440 ssize_t result;
441
442 mutex_lock(&io.sim_mutex);
443
444 io.fd = fd;
445 io.buf = (void*)buf;
446 io.count = count;
447
448 io_trigger_and_wait(IO_WRITE);
449
450 result = io.result;
451
452 mutex_unlock(&io.sim_mutex);
453
454 return result;
455}
456
290int sim_mkdir(const char *name) 457int sim_mkdir(const char *name)
291{ 458{
292#ifdef __PCTOOL__ 459#ifdef __PCTOOL__