Skip to content

Commit

Permalink
Merge pull request #7156 from RetroSven/master
Browse files Browse the repository at this point in the history
 push save state into background for cores that need the emulator to be running during serialization
  • Loading branch information
inactive123 authored Aug 30, 2018
2 parents f16ec70 + 75abd1f commit 02e23be
Showing 1 changed file with 80 additions and 62 deletions.
142 changes: 80 additions & 62 deletions tasks/task_save.c
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,33 @@ static void task_save_handler_finished(retro_task_t *task,
free(state);
}

void* get_serialized_data(const char *path, size_t serial_size)
{
retro_ctx_serialize_info_t serial_info;
bool ret = false;
void *data = NULL;

data = malloc(serial_size);

if (!data)
return NULL;

RARCH_LOG("%s: %d %s.\n",
msg_hash_to_str(MSG_STATE_SIZE),
(int)serial_size,
msg_hash_to_str(MSG_BYTES));

serial_info.data = data;
serial_info.size = serial_size;
ret = core_serialize(&serial_info);
if ( !ret )
{
free(data) ;
return NULL ;
}
return data ;
}

/**
* task_save_handler:
* @task : the task being worked on
Expand All @@ -576,9 +603,22 @@ static void task_save_handler(retro_task_t *task)
return;
}

if (!state->data)
{
state->data = get_serialized_data(state->path, state->size) ;
}

remaining = MIN(state->size - state->written, SAVE_STATE_CHUNK);
written = (int)intfstream_write(state->file,
(uint8_t*)state->data + state->written, remaining);

if ( state->data )
{
written = (int)intfstream_write(state->file,
(uint8_t*)state->data + state->written, remaining);
}
else
{
written = 0 ;
}

state->written += written;

Expand Down Expand Up @@ -1134,6 +1174,7 @@ static void task_push_load_and_save_state(const char *path, void *data,
free(task);
}


/**
* content_save_state:
* @path : path of saved state that shall be written to.
Expand All @@ -1144,85 +1185,62 @@ static void task_push_load_and_save_state(const char *path, void *data,
**/
bool content_save_state(const char *path, bool save_to_disk, bool autosave)
{
retro_ctx_serialize_info_t serial_info;
//retro_ctx_serialize_info_t serial_info;
retro_ctx_size_info_t info;
bool ret = false;
void *data = NULL;

core_serialize_size(&info);

RARCH_LOG("%s: \"%s\".\n",
msg_hash_to_str(MSG_SAVING_STATE),
path);

if (info.size == 0)
return false;

data = malloc(info.size);

if (!data)
return false;

RARCH_LOG("%s: %d %s.\n",
msg_hash_to_str(MSG_STATE_SIZE),
(int)info.size,
msg_hash_to_str(MSG_BYTES));

serial_info.data = data;
serial_info.size = info.size;
ret = core_serialize(&serial_info);

if (ret)
if (save_to_disk)
{
if (save_to_disk)
if (filestream_exists(path) && !autosave)
{
if (filestream_exists(path) && !autosave)
{
/* Before overwritting the savestate file, load it into a buffer
to allow undo_save_state() to work */
/* TODO/FIXME - Use msg_hash_to_str here */
RARCH_LOG("%s ...\n",
msg_hash_to_str(MSG_FILE_ALREADY_EXISTS_SAVING_TO_BACKUP_BUFFER));
/* Before overwritting the savestate file, load it into a buffer
to allow undo_save_state() to work */
/* TODO/FIXME - Use msg_hash_to_str here */
RARCH_LOG("%s ...\n",
msg_hash_to_str(MSG_FILE_ALREADY_EXISTS_SAVING_TO_BACKUP_BUFFER));

task_push_load_and_save_state(path, data, info.size, true, autosave);
}
else
task_push_save_state(path, data, info.size, autosave);
task_push_load_and_save_state(path, data, info.size, true, autosave);
}
else
task_push_save_state(path, data, info.size, autosave);
}
else
{
data = get_serialized_data(path, info.size) ;
if ( data == NULL )
{
/* save_to_disk is false, which means we are saving the state
in undo_load_buf to allow content_undo_load_state() to restore it */

/* If we were holding onto an old state already, clean it up first */
if (undo_load_buf.data)
{
free(undo_load_buf.data);
undo_load_buf.data = NULL;
}
RARCH_ERR("%s \"%s\".\n",
msg_hash_to_str(MSG_FAILED_TO_SAVE_STATE_TO),
path);
return false ;
}
/* save_to_disk is false, which means we are saving the state
in undo_load_buf to allow content_undo_load_state() to restore it */

undo_load_buf.data = malloc(info.size);
if (!undo_load_buf.data)
{
free(data);
return false;
}
/* If we were holding onto an old state already, clean it up first */
if (undo_load_buf.data)
{
free(undo_load_buf.data);
undo_load_buf.data = NULL;
}

memcpy(undo_load_buf.data, data, info.size);
undo_load_buf.data = malloc(info.size);
if (!undo_load_buf.data)
{
free(data);
undo_load_buf.size = info.size;
strlcpy(undo_load_buf.path, path, sizeof(undo_load_buf.path));
return false;
}
}
else
{

memcpy(undo_load_buf.data, data, info.size);
free(data);
RARCH_ERR("%s \"%s\".\n",
msg_hash_to_str(MSG_FAILED_TO_SAVE_STATE_TO),
path);
undo_load_buf.size = info.size;
strlcpy(undo_load_buf.path, path, sizeof(undo_load_buf.path));
}

return ret;
return true;
}

/**
Expand Down

0 comments on commit 02e23be

Please sign in to comment.