static void gx_devthread(void *a) { unsigned i; while (!gx_stop_dev_thread) { slock_lock(gx_device_mutex); for (i = 0; i < GX_DEVICE_END; i++) { if (gx_devices[i].mounted) { if (!gx_devices[i].interface->isInserted()) { char n[8]; gx_devices[i].mounted = false; snprintf(n, sizeof(n), "%s:", gx_devices[i].name); fatUnmount(n); } } else if (gx_devices[i].interface->startup() && gx_devices[i].interface->isInserted()) gx_devices[i].mounted = fatMountSimple(gx_devices[i].name, gx_devices[i].interface); } slock_unlock(gx_device_mutex); slock_lock(gx_device_cond_mutex); scond_wait_timeout(gx_device_cond, gx_device_cond_mutex, 1000000); slock_unlock(gx_device_cond_mutex); } }
/** * autosave_thread: * @data : pointer to autosave object * * Callback function for (threaded) autosave. **/ static void autosave_thread(void *data) { bool first_log = true; autosave_t *save = (autosave_t*)data; while (!save->quit) { bool differ; autosave_lock(save); differ = memcmp(save->buffer, save->retro_buffer, save->bufsize) != 0; if (differ) memcpy(save->buffer, save->retro_buffer, save->bufsize); autosave_unlock(save); if (differ) { /* Should probably deal with this more elegantly. */ FILE *file = fopen(save->path, "wb"); if (file) { bool failed = false; /* Avoid spamming down stderr ... */ if (first_log) { RARCH_LOG("Autosaving SRAM to \"%s\", will continue to check every %u seconds ...\n", save->path, save->interval); first_log = false; } else RARCH_LOG("SRAM changed ... autosaving ...\n"); failed |= fwrite(save->buffer, 1, save->bufsize, file) != save->bufsize; failed |= fflush(file) != 0; failed |= fclose(file) != 0; if (failed) RARCH_WARN("Failed to autosave SRAM. Disk might be full.\n"); } } slock_lock(save->cond_lock); if (!save->quit) scond_wait_timeout(save->cond, save->cond_lock, save->interval * 1000000LL); slock_unlock(save->cond_lock); } }
static ssize_t coreaudio_write(void *data, const void *buf_, size_t size, bool is_perfcnt_enable) { coreaudio_t *dev = (coreaudio_t*)data; const uint8_t *buf = (const uint8_t*)buf_; size_t written = 0; while (!g_interrupted && size > 0) { size_t write_avail; slock_lock(dev->lock); write_avail = fifo_write_avail(dev->buffer); if (write_avail > size) write_avail = size; fifo_write(dev->buffer, buf, write_avail); buf += write_avail; written += write_avail; size -= write_avail; if (dev->nonblock) { slock_unlock(dev->lock); break; } #if TARGET_OS_IPHONE if (write_avail == 0 && !scond_wait_timeout( dev->cond, dev->lock, 3000000)) g_interrupted = true; #else if (write_avail == 0) scond_wait(dev->cond, dev->lock); #endif slock_unlock(dev->lock); } return written; }
static bool thread_frame(void *data, const void *frame_, unsigned width, unsigned height, unsigned pitch, const char *msg) { unsigned copy_stride; const uint8_t *src = NULL; uint8_t *dst = NULL; thread_video_t *thr = (thread_video_t*)data; /* If called from within read_viewport, we're actually in the * driver thread, so just render directly. */ if (thr->frame.within_thread) { thread_update_driver_state(thr); if (thr->driver && thr->driver->frame) return thr->driver->frame(thr->driver_data, frame_, width, height, pitch, msg); return false; } RARCH_PERFORMANCE_INIT(thr_frame); RARCH_PERFORMANCE_START(thr_frame); copy_stride = width * (thr->info.rgb32 ? sizeof(uint32_t) : sizeof(uint16_t)); src = (const uint8_t*)frame_; dst = thr->frame.buffer; slock_lock(thr->lock); if (!thr->nonblock) { settings_t *settings = config_get_ptr(); retro_time_t target_frame_time = (retro_time_t) roundf(1000000 / settings->video.refresh_rate); retro_time_t target = thr->last_time + target_frame_time; /* Ideally, use absolute time, but that is only a good idea on POSIX. */ while (thr->frame.updated) { retro_time_t current = rarch_get_time_usec(); retro_time_t delta = target - current; if (delta <= 0) break; if (!scond_wait_timeout(thr->cond_cmd, thr->lock, delta)) break; } } /* Drop frame if updated flag is still set, as thread is * still working on last frame. */ if (!thr->frame.updated) { if (src) { unsigned h; for (h = 0; h < height; h++, src += pitch, dst += copy_stride) memcpy(dst, src, copy_stride); } thr->frame.updated = true; thr->frame.width = width; thr->frame.height = height; thr->frame.pitch = copy_stride; if (msg) strlcpy(thr->frame.msg, msg, sizeof(thr->frame.msg)); else *thr->frame.msg = '\0'; scond_signal(thr->cond_thread); #if defined(HAVE_MENU) if (thr->texture.enable) { while (thr->frame.updated) scond_wait(thr->cond_cmd, thr->lock); } #endif thr->hit_count++; } else thr->miss_count++; slock_unlock(thr->lock); RARCH_PERFORMANCE_STOP(thr_frame); thr->last_time = rarch_get_time_usec(); return true; }
static bool thread_frame(void *data, const void *frame_, unsigned width, unsigned height, unsigned pitch, const char *msg) { RARCH_PERFORMANCE_INIT(thread_frame); RARCH_PERFORMANCE_START(thread_frame); thread_video_t *thr = (thread_video_t*)data; unsigned copy_stride = width * (thr->info.rgb32 ? sizeof(uint32_t) : sizeof(uint16_t)); const uint8_t *src = (const uint8_t*)frame_; uint8_t *dst = thr->frame.buffer; slock_lock(thr->lock); // scond_wait_timeout cannot be implemented on consoles. #ifndef RARCH_CONSOLE if (!thr->nonblock) { retro_time_t target = thr->last_time + thr->target_frame_time; // Ideally, use absolute time, but that is only a good idea on POSIX. while (thr->frame.updated) { retro_time_t current = rarch_get_time_usec(); retro_time_t delta = target - current; if (delta <= 0) break; if (!scond_wait_timeout(thr->cond_cmd, thr->lock, delta)) break; } } #endif // Drop frame if updated flag is still set, as thread is still working on last frame. if (!thr->frame.updated) { if (src) { unsigned h; for (h = 0; h < height; h++, src += pitch, dst += copy_stride) memcpy(dst, src, copy_stride); } thr->frame.updated = true; thr->frame.width = width; thr->frame.height = height; thr->frame.pitch = copy_stride; if (msg) strlcpy(thr->frame.msg, msg, sizeof(thr->frame.msg)); else *thr->frame.msg = '\0'; scond_signal(thr->cond_thread); #if defined(HAVE_MENU) if (thr->texture.enable) { while (thr->frame.updated) scond_wait(thr->cond_cmd, thr->lock); } #endif thr->hit_count++; } else thr->miss_count++; slock_unlock(thr->lock); RARCH_PERFORMANCE_STOP(thread_frame); thr->last_time = rarch_get_time_usec(); return true; }