summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2025-04-18 21:30:32 -0500
committerJordan Woyak <jordan.woyak@gmail.com>2025-04-19 17:29:56 -0500
commitac3dbe22949bb988bdc60a85bc3606f2d3bdc958 (patch)
tree812846d57d99c9fdb879ccca5520de77fc0838eb /Source
parent12dcd6c28558b1a1d53711805f8327f271e31667 (diff)
Core/State: Use UniqueBuffer instead of make_unique and std::vector for save state buffers.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/State.cpp88
-rw-r--r--Source/Core/Core/State.h6
2 files changed, 40 insertions, 54 deletions
diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp
index 44465b3f42..473e41de98 100644
--- a/Source/Core/Core/State.cpp
+++ b/Source/Core/Core/State.cpp
@@ -4,7 +4,6 @@
#include "Core/State.h"
#include <algorithm>
-#include <atomic>
#include <condition_variable>
#include <filesystem>
#include <locale>
@@ -12,7 +11,6 @@
#include <memory>
#include <mutex>
#include <string>
-#include <thread>
#include <utility>
#include <vector>
@@ -31,12 +29,10 @@
#include "Common/MsgHandler.h"
#include "Common/Thread.h"
#include "Common/TimeUtil.h"
-#include "Common/Timer.h"
#include "Common/Version.h"
#include "Common/WorkQueueThread.h"
#include "Core/AchievementManager.h"
-#include "Core/Config/AchievementSettings.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/CoreTiming.h"
@@ -46,7 +42,7 @@
#include "Core/HW/Wiimote.h"
#include "Core/Host.h"
#include "Core/Movie.h"
-#include "Core/NetPlayClient.h"
+#include "Core/NetPlayProto.h"
#include "Core/PowerPC/PowerPC.h"
#include "Core/System.h"
@@ -71,14 +67,14 @@ static unsigned char __LZO_MMODEL out[OUT_LEN];
static AfterLoadCallbackFunc s_on_after_load_callback;
// Temporary undo state buffer
-static std::vector<u8> s_undo_load_buffer;
+static Common::UniqueBuffer<u8> s_undo_load_buffer;
static std::mutex s_undo_load_buffer_mutex;
static std::mutex s_load_or_save_in_progress_mutex;
struct CompressAndDumpState_args
{
- std::vector<u8> buffer_vector;
+ Common::UniqueBuffer<u8> buffer;
std::string filename;
std::shared_ptr<Common::Event> state_write_done_event;
};
@@ -205,7 +201,7 @@ static void DoState(Core::System& system, PointerWrap& p)
#endif // USE_RETRO_ACHIEVEMENTS
}
-void LoadFromBuffer(Core::System& system, std::vector<u8>& buffer)
+void LoadFromBuffer(Core::System& system, Common::UniqueBuffer<u8>& buffer)
{
if (NetPlay::IsNetPlayRunning())
{
@@ -229,20 +225,21 @@ void LoadFromBuffer(Core::System& system, std::vector<u8>& buffer)
true);
}
-void SaveToBuffer(Core::System& system, std::vector<u8>& buffer)
+void SaveToBuffer(Core::System& system, Common::UniqueBuffer<u8>& buffer)
{
Core::RunOnCPUThread(
system,
[&] {
u8* ptr = nullptr;
PointerWrap p_measure(&ptr, 0, PointerWrap::Mode::Measure);
-
DoState(system, p_measure);
- const size_t buffer_size = reinterpret_cast<size_t>(ptr);
- buffer.resize(buffer_size);
+
+ const size_t new_buffer_size = ptr - (u8*)(nullptr);
+ if (new_buffer_size > buffer.size())
+ buffer.reset(new_buffer_size);
ptr = buffer.data();
- PointerWrap p(&ptr, buffer_size, PointerWrap::Mode::Write);
+ PointerWrap p(&ptr, buffer.size(), PointerWrap::Mode::Write);
DoState(system, p);
},
true);
@@ -318,15 +315,14 @@ static void CompressBufferToFile(const u8* raw_buffer, u64 size, File::IOFile& f
while (true)
{
- u64 bytes_left_to_compress = size - total_bytes_compressed;
+ const u64 bytes_left_to_compress = size - total_bytes_compressed;
- int bytes_to_compress =
+ const int bytes_to_compress =
static_cast<int>(std::min(static_cast<u64>(LZ4_MAX_INPUT_SIZE), bytes_left_to_compress));
- int compressed_buffer_size = LZ4_compressBound(bytes_to_compress);
- auto compressed_buffer = std::make_unique<char[]>(compressed_buffer_size);
- s32 compressed_len =
- LZ4_compress_default(reinterpret_cast<const char*>(raw_buffer) + total_bytes_compressed,
- compressed_buffer.get(), bytes_to_compress, compressed_buffer_size);
+ Common::UniqueBuffer<char> compressed_buffer(LZ4_compressBound(bytes_to_compress));
+ const int compressed_len = LZ4_compress_default(
+ reinterpret_cast<const char*>(raw_buffer) + total_bytes_compressed, compressed_buffer.get(),
+ bytes_to_compress, int(compressed_buffer.size()));
if (compressed_len == 0)
{
@@ -380,8 +376,8 @@ static void WriteHeadersToFile(size_t uncompressed_size, File::IOFile& f)
static void CompressAndDumpState(Core::System& system, CompressAndDumpState_args& save_args)
{
- const u8* const buffer_data = save_args.buffer_vector.data();
- const size_t buffer_size = save_args.buffer_vector.size();
+ const u8* const buffer_data = save_args.buffer.data();
+ const size_t buffer_size = save_args.buffer.size();
const std::string& filename = save_args.filename;
// Find free temporary filename.
@@ -482,11 +478,10 @@ void SaveAs(Core::System& system, const std::string& filename, bool wait)
u8* ptr = nullptr;
PointerWrap p_measure(&ptr, 0, PointerWrap::Mode::Measure);
DoState(system, p_measure);
- const size_t buffer_size = reinterpret_cast<size_t>(ptr);
+ const size_t buffer_size = ptr - (u8*)(nullptr);
// Then actually do the write.
- std::vector<u8> current_buffer;
- current_buffer.resize(buffer_size);
+ Common::UniqueBuffer<u8> current_buffer(buffer_size);
ptr = current_buffer.data();
PointerWrap p(&ptr, buffer_size, PointerWrap::Mode::Write);
DoState(system, p);
@@ -498,7 +493,7 @@ void SaveAs(Core::System& system, const std::string& filename, bool wait)
std::shared_ptr<Common::Event> sync_event;
CompressAndDumpState_args save_args;
- save_args.buffer_vector = std::move(current_buffer);
+ save_args.buffer = std::move(current_buffer);
save_args.filename = filename;
if (wait)
{
@@ -531,8 +526,7 @@ static bool GetVersionFromLZO(StateHeader& header, File::IOFile& f)
// Just read the first block, since it will contain the full revision string
lzo_uint32 cur_len = 0; // size of compressed bytes
lzo_uint new_len = 0; // size of uncompressed bytes
- std::vector<u8> buffer;
- buffer.resize(header.legacy_header.lzo_size);
+ Common::UniqueBuffer<u8> buffer(header.legacy_header.lzo_size);
if (!f.ReadArray(&cur_len, 1) || !f.ReadBytes(out, cur_len))
return false;
@@ -563,11 +557,9 @@ static bool GetVersionFromLZO(StateHeader& header, File::IOFile& f)
// Read in the string
if (buffer.size() >= sizeof(StateHeaderVersion) + header.version_header.version_string_length)
{
- auto version_buffer = std::make_unique<char[]>(header.version_header.version_string_length);
- memcpy(version_buffer.get(), buffer.data() + sizeof(StateHeaderVersion),
- header.version_header.version_string_length);
- header.version_string =
- std::string(version_buffer.get(), header.version_header.version_string_length);
+ header.version_string.assign(
+ reinterpret_cast<char*>(buffer.data() + sizeof(StateHeaderVersion)),
+ header.version_header.version_string_length);
}
else
{
@@ -613,15 +605,14 @@ static bool ReadStateHeaderFromFile(StateHeader& header, File::IOFile& f,
return false;
}
- auto version_buffer = std::make_unique<char[]>(header.version_header.version_string_length);
- if (!f.ReadBytes(version_buffer.get(), header.version_header.version_string_length))
+ std::string version_buffer(header.version_header.version_string_length, '\0');
+ if (!f.ReadBytes(version_buffer.data(), version_buffer.size()))
{
Core::DisplayMessage("Failed to read state version string", 2000);
return false;
}
- header.version_string =
- std::string(version_buffer.get(), header.version_header.version_string_length);
+ header.version_string = std::move(version_buffer);
}
return true;
@@ -661,9 +652,9 @@ u64 GetUnixTimeOfSlot(int slot)
(DOUBLE_TIME_OFFSET * MS_PER_SEC);
}
-static bool DecompressLZ4(std::vector<u8>& raw_buffer, u64 size, File::IOFile& f)
+static bool DecompressLZ4(Common::UniqueBuffer<u8>& raw_buffer, u64 size, File::IOFile& f)
{
- raw_buffer.resize(size);
+ raw_buffer.reset(size);
u64 total_bytes_read = 0;
while (true)
@@ -681,7 +672,7 @@ static bool DecompressLZ4(std::vector<u8>& raw_buffer, u64 size, File::IOFile& f
return false;
}
- auto compressed_data = std::make_unique<char[]>(compressed_data_len);
+ Common::UniqueBuffer<char> compressed_data(compressed_data_len);
if (!f.ReadBytes(compressed_data.get(), compressed_data_len))
{
PanicAlertFmt("Could not read state data");
@@ -764,7 +755,7 @@ static bool ValidateHeaders(const StateHeader& header)
return success;
}
-static void LoadFileStateData(const std::string& filename, std::vector<u8>& ret_data)
+static void LoadFileStateData(const std::string& filename, Common::UniqueBuffer<u8>& ret_data)
{
File::IOFile f;
@@ -802,7 +793,7 @@ static void LoadFileStateData(const std::string& filename, std::vector<u8>& ret_
return;
}
- std::vector<u8> buffer;
+ Common::UniqueBuffer<u8> buffer;
switch (extended_header.base_header.compression_type)
{
@@ -828,7 +819,7 @@ static void LoadFileStateData(const std::string& filename, std::vector<u8>& ret_
}
const auto size = static_cast<size_t>(file_size - header_len);
- buffer.resize(size);
+ buffer.reset(size);
if (!f.ReadBytes(buffer.data(), size))
{
@@ -888,7 +879,7 @@ void LoadAs(Core::System& system, const std::string& filename)
// brackets here are so buffer gets freed ASAP
{
- std::vector<u8> buffer;
+ Common::UniqueBuffer<u8> buffer;
LoadFileStateData(filename, buffer);
if (!buffer.empty())
@@ -954,13 +945,8 @@ void Shutdown()
{
s_save_thread.Shutdown();
- // swapping with an empty vector, rather than clear()ing
- // this gives a better guarantee to free the allocated memory right NOW (as opposed to, actually,
- // never)
- {
- std::lock_guard lk(s_undo_load_buffer_mutex);
- std::vector<u8>().swap(s_undo_load_buffer);
- }
+ std::lock_guard lk(s_undo_load_buffer_mutex);
+ s_undo_load_buffer.reset();
}
static std::string MakeStateFilename(int number)
diff --git a/Source/Core/Core/State.h b/Source/Core/Core/State.h
index 626a0ecca4..1e4ba0029b 100644
--- a/Source/Core/Core/State.h
+++ b/Source/Core/Core/State.h
@@ -9,8 +9,8 @@
#include <functional>
#include <string>
#include <type_traits>
-#include <vector>
+#include "Common/Buffer.h"
#include "Common/CommonTypes.h"
namespace Core
@@ -106,8 +106,8 @@ void Load(Core::System& system, int slot);
void SaveAs(Core::System& system, const std::string& filename, bool wait = false);
void LoadAs(Core::System& system, const std::string& filename);
-void SaveToBuffer(Core::System& system, std::vector<u8>& buffer);
-void LoadFromBuffer(Core::System& system, std::vector<u8>& buffer);
+void SaveToBuffer(Core::System& system, Common::UniqueBuffer<u8>& buffer);
+void LoadFromBuffer(Core::System& system, const Common::UniqueBuffer<u8>& buffer);
void LoadLastSaved(Core::System& system, int i = 1);
void SaveFirstSaved(Core::System& system);