diff options
Diffstat (limited to 'uisimulator/common')
-rw-r--r-- | uisimulator/common/io.c | 127 |
1 files changed, 21 insertions, 106 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 **/ |
190 | enum | 192 | enum |
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 | ||
199 | struct sim_io | 198 | struct 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 | ||
213 | static struct sim_io io; | 208 | static struct sim_io io; |
214 | 209 | ||
215 | static 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 | |||
244 | bool 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 | |||
281 | int ata_init(void) | 210 | int 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 | ||
288 | void sim_io_shutdown(void) | 217 | static 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 | |||
303 | static 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 | ||
322 | static const char *get_sim_rootdir() | 241 | static 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 | ||