From 534c923b6b99676c8fd3424f26a659ef6ab537f5 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 27 May 2016 17:52:20 +0200 Subject: [PATCH] Remove autosave.c --- Makefile.common | 3 +- autosave.c | 273 ------------------------------------------ griffin/griffin.c | 1 - tasks/task_save_ram.c | 249 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 250 insertions(+), 276 deletions(-) delete mode 100644 autosave.c diff --git a/Makefile.common b/Makefile.common index c4eedb90fc..2bf73d6d08 100644 --- a/Makefile.common +++ b/Makefile.common @@ -510,8 +510,7 @@ ifeq ($(HAVE_FREETYPE), 1) endif ifeq ($(HAVE_THREADS), 1) - OBJ += autosave.o \ - libretro-common/rthreads/rthreads.o \ + OBJ += libretro-common/rthreads/rthreads.o \ libretro-common/rthreads/rsemaphore.o \ gfx/video_thread_wrapper.o \ audio/audio_thread_wrapper.o diff --git a/autosave.c b/autosave.c deleted file mode 100644 index de4c659d22..0000000000 --- a/autosave.c +++ /dev/null @@ -1,273 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2014 - Hans-Kristian Arntzen - * Copyright (C) 2011-2016 - Daniel De Matteis - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . - */ - -#include -#include -#include - -#include - -#include -#include - -#include "autosave.h" -#include "configuration.h" -#include "msg_hash.h" -#include "runloop.h" -#include "core.h" -#include "verbosity.h" - -/* Autosave support. */ -struct autosave_st -{ - autosave_t **list; - unsigned num; -}; - -struct autosave -{ - volatile bool quit; - slock_t *lock; - - slock_t *cond_lock; - scond_t *cond; - sthread_t *thread; - - void *buffer; - const void *retro_buffer; - const char *path; - size_t bufsize; - unsigned interval; -}; - -static struct autosave_st autosave_state; - -/** - * 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; - - slock_lock(save->lock); - differ = memcmp(save->buffer, save->retro_buffer, - save->bufsize) != 0; - if (differ) - memcpy(save->buffer, save->retro_buffer, save->bufsize); - slock_unlock(save->lock); - - 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); - } -} - -/** - * autosave_new: - * @path : path to autosave file - * @data : pointer to buffer - * @size : size of @data buffer - * @interval : interval at which saves should be performed. - * - * Create and initialize autosave object. - * - * Returns: pointer to new autosave_t object if successful, otherwise - * NULL. - **/ -static autosave_t *autosave_new(const char *path, - const void *data, size_t size, - unsigned interval) -{ - autosave_t *handle = (autosave_t*)calloc(1, sizeof(*handle)); - if (!handle) - goto error; - - handle->bufsize = size; - handle->interval = interval; - handle->path = path; - handle->buffer = malloc(size); - handle->retro_buffer = data; - - if (!handle->buffer) - goto error; - - memcpy(handle->buffer, handle->retro_buffer, handle->bufsize); - - handle->lock = slock_new(); - handle->cond_lock = slock_new(); - handle->cond = scond_new(); - - handle->thread = sthread_create(autosave_thread, handle); - - return handle; - -error: - if (handle) - free(handle); - return NULL; -} - -/** - * autosave_free: - * @handle : pointer to autosave object - * - * Frees autosave object. - **/ -static void autosave_free(autosave_t *handle) -{ - if (!handle) - return; - - slock_lock(handle->cond_lock); - handle->quit = true; - slock_unlock(handle->cond_lock); - scond_signal(handle->cond); - sthread_join(handle->thread); - - slock_free(handle->lock); - slock_free(handle->cond_lock); - scond_free(handle->cond); - - free(handle->buffer); - free(handle); -} - -/** - * autosave_lock: - * - * Lock autosave. - **/ -void autosave_lock(void) -{ - unsigned i; - - for (i = 0; i < autosave_state.num; i++) - { - if (autosave_state.list[i]) - slock_lock(autosave_state.list[i]->lock); - } -} - -/** - * autosave_unlock: - * - * Unlocks autosave. - **/ -void autosave_unlock(void) -{ - unsigned i; - - for (i = 0; i < autosave_state.num; i++) - { - if (autosave_state.list[i]) - slock_unlock(autosave_state.list[i]->lock); - } -} - -void autosave_init(void) -{ - unsigned i; - autosave_t **list = NULL; - settings_t *settings = config_get_ptr(); - global_t *global = global_get_ptr(); - - if (settings->autosave_interval < 1 || !global->savefiles) - return; - - list = (autosave_t**)calloc(global->savefiles->size, - sizeof(*autosave_state.list)); - if (!list) - return; - - autosave_state.list = list; - autosave_state.num = global->savefiles->size; - - for (i = 0; i < global->savefiles->size; i++) - { - retro_ctx_memory_info_t mem_info; - const char *path = global->savefiles->elems[i].data; - unsigned type = global->savefiles->elems[i].attr.i; - - mem_info.id = type; - - core_get_memory(&mem_info); - - if (mem_info.size <= 0) - continue; - - autosave_state.list[i] = autosave_new(path, - mem_info.data, - mem_info.size, - settings->autosave_interval); - - if (!autosave_state.list[i]) - RARCH_WARN("%s\n", msg_hash_to_str(MSG_AUTOSAVE_FAILED)); - } -} - -void autosave_deinit(void) -{ - unsigned i; - - for (i = 0; i < autosave_state.num; i++) - autosave_free(autosave_state.list[i]); - - if (autosave_state.list) - free(autosave_state.list); - - autosave_state.list = NULL; - autosave_state.num = 0; -} diff --git a/griffin/griffin.c b/griffin/griffin.c index 2d6ab8ea1b..43b9320303 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -790,7 +790,6 @@ THREAD #include "../libretro-common/rthreads/rsemaphore.c" #include "../gfx/video_thread_wrapper.c" #include "../audio/audio_thread_wrapper.c" -#include "../autosave.c" #endif diff --git a/tasks/task_save_ram.c b/tasks/task_save_ram.c index d32587b53c..3665119502 100644 --- a/tasks/task_save_ram.c +++ b/tasks/task_save_ram.c @@ -20,12 +20,19 @@ #include #include +#include #include #include +#include #include "../core.h" #include "../msg_hash.h" #include "../verbosity.h" +#include "../autosave.h" +#include "../configuration.h" +#include "../msg_hash.h" +#include "../runloop.h" + #include "tasks_internal.h" /* TODO/FIXME - turn this into actual task */ @@ -36,6 +43,248 @@ struct ram_type int type; }; +/* Autosave support. */ +struct autosave_st +{ + autosave_t **list; + unsigned num; +}; + +struct autosave +{ + volatile bool quit; + slock_t *lock; + + slock_t *cond_lock; + scond_t *cond; + sthread_t *thread; + + void *buffer; + const void *retro_buffer; + const char *path; + size_t bufsize; + unsigned interval; +}; + +static struct autosave_st autosave_state; + +/** + * 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; + + slock_lock(save->lock); + differ = memcmp(save->buffer, save->retro_buffer, + save->bufsize) != 0; + if (differ) + memcpy(save->buffer, save->retro_buffer, save->bufsize); + slock_unlock(save->lock); + + 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); + } +} + +/** + * autosave_new: + * @path : path to autosave file + * @data : pointer to buffer + * @size : size of @data buffer + * @interval : interval at which saves should be performed. + * + * Create and initialize autosave object. + * + * Returns: pointer to new autosave_t object if successful, otherwise + * NULL. + **/ +static autosave_t *autosave_new(const char *path, + const void *data, size_t size, + unsigned interval) +{ + autosave_t *handle = (autosave_t*)calloc(1, sizeof(*handle)); + if (!handle) + goto error; + + handle->bufsize = size; + handle->interval = interval; + handle->path = path; + handle->buffer = malloc(size); + handle->retro_buffer = data; + + if (!handle->buffer) + goto error; + + memcpy(handle->buffer, handle->retro_buffer, handle->bufsize); + + handle->lock = slock_new(); + handle->cond_lock = slock_new(); + handle->cond = scond_new(); + + handle->thread = sthread_create(autosave_thread, handle); + + return handle; + +error: + if (handle) + free(handle); + return NULL; +} + +/** + * autosave_free: + * @handle : pointer to autosave object + * + * Frees autosave object. + **/ +static void autosave_free(autosave_t *handle) +{ + if (!handle) + return; + + slock_lock(handle->cond_lock); + handle->quit = true; + slock_unlock(handle->cond_lock); + scond_signal(handle->cond); + sthread_join(handle->thread); + + slock_free(handle->lock); + slock_free(handle->cond_lock); + scond_free(handle->cond); + + free(handle->buffer); + free(handle); +} + +/** + * autosave_lock: + * + * Lock autosave. + **/ +void autosave_lock(void) +{ + unsigned i; + + for (i = 0; i < autosave_state.num; i++) + { + if (autosave_state.list[i]) + slock_lock(autosave_state.list[i]->lock); + } +} + +/** + * autosave_unlock: + * + * Unlocks autosave. + **/ +void autosave_unlock(void) +{ + unsigned i; + + for (i = 0; i < autosave_state.num; i++) + { + if (autosave_state.list[i]) + slock_unlock(autosave_state.list[i]->lock); + } +} + +void autosave_init(void) +{ + unsigned i; + autosave_t **list = NULL; + settings_t *settings = config_get_ptr(); + global_t *global = global_get_ptr(); + + if (settings->autosave_interval < 1 || !global->savefiles) + return; + + list = (autosave_t**)calloc(global->savefiles->size, + sizeof(*autosave_state.list)); + if (!list) + return; + + autosave_state.list = list; + autosave_state.num = global->savefiles->size; + + for (i = 0; i < global->savefiles->size; i++) + { + retro_ctx_memory_info_t mem_info; + const char *path = global->savefiles->elems[i].data; + unsigned type = global->savefiles->elems[i].attr.i; + + mem_info.id = type; + + core_get_memory(&mem_info); + + if (mem_info.size <= 0) + continue; + + autosave_state.list[i] = autosave_new(path, + mem_info.data, + mem_info.size, + settings->autosave_interval); + + if (!autosave_state.list[i]) + RARCH_WARN("%s\n", msg_hash_to_str(MSG_AUTOSAVE_FAILED)); + } +} + +void autosave_deinit(void) +{ + unsigned i; + + for (i = 0; i < autosave_state.num; i++) + autosave_free(autosave_state.list[i]); + + if (autosave_state.list) + free(autosave_state.list); + + autosave_state.list = NULL; + autosave_state.num = 0; +} + /** * content_load_ram_file: * @path : path of RAM state that will be loaded from.