diff options
Diffstat (limited to 'uisimulator/common')
-rw-r--r-- | uisimulator/common/io.c | 169 |
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 **/ | ||
182 | enum | ||
183 | { | ||
184 | IO_QUIT = -1, | ||
185 | IO_OPEN, | ||
186 | IO_CLOSE, | ||
187 | IO_READ, | ||
188 | IO_WRITE, | ||
189 | }; | ||
190 | |||
191 | struct 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 | |||
205 | static struct sim_io io; | ||
206 | |||
207 | static 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 | |||
236 | void 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 | |||
272 | void 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 | |||
287 | static 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 | |||
178 | MYDIR *sim_opendir(const char *name) | 306 | MYDIR *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 | ||
418 | ssize_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 | |||
438 | ssize_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 | |||
290 | int sim_mkdir(const char *name) | 457 | int sim_mkdir(const char *name) |
291 | { | 458 | { |
292 | #ifdef __PCTOOL__ | 459 | #ifdef __PCTOOL__ |