Optimize RPCS3.log and limit it to 64 MiB

Use memory-mapped file for writing
This commit is contained in:
Nekotekina 2017-08-23 20:44:31 +03:00
parent 1716db14ed
commit 025a09ed87
3 changed files with 51 additions and 5 deletions

View File

@ -764,7 +764,13 @@ fs::file::file(const std::string& path, bs_t<open_mode> mode)
disp = test(mode & fs::trunc) ? TRUNCATE_EXISTING : OPEN_EXISTING;
}
const HANDLE handle = CreateFileW(to_wchar(path).get(), access, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD share = 0;
if (!test(mode & fs::unshare))
{
share |= FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
}
const HANDLE handle = CreateFileW(to_wchar(path).get(), access, share, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE)
{

View File

@ -25,6 +25,7 @@ namespace fs
create,
trunc,
excl,
unshare,
__bitset_enum_max
};
@ -35,6 +36,7 @@ namespace fs
constexpr auto create = +open_mode::create; // Create file if it doesn't exist
constexpr auto trunc = +open_mode::trunc; // Clear opened file if it's not empty
constexpr auto excl = +open_mode::excl; // Failure if the file already exists (used with `create`)
constexpr auto unshare = +open_mode::unshare; // Prevent opening the file twice
constexpr auto rewrite = open_mode::write + open_mode::create + open_mode::trunc;

View File

@ -9,9 +9,11 @@
#include <unordered_map>
#ifdef _WIN32
#define NOMINMAX
#include <Windows.h>
#else
#include <chrono>
#include <sys/mman.h>
#endif
static std::string empty_string()
@ -45,15 +47,22 @@ void fmt_class_string<logs::level>::format(std::string& out, u64 arg)
namespace logs
{
constexpr std::size_t s_log_size = 64 * 1024 * 1024;
class file_writer
{
// Could be memory-mapped file
fs::file m_file;
#ifdef _WIN32
::HANDLE m_fmap;
#endif
atomic_t<std::size_t> m_pos{0};
uchar* m_fptr;
public:
file_writer(const std::string& name);
virtual ~file_writer() = default;
virtual ~file_writer();
// Append raw data
void log(const char* text, std::size_t size);
@ -63,6 +72,8 @@ namespace logs
{
file_listener(const std::string& name);
virtual ~file_listener() = default;
// Encode level, current thread name, channel name and write log message
virtual void log(u64 stamp, const message& msg, const std::string& prefix, const std::string& text) override;
};
@ -273,10 +284,17 @@ logs::file_writer::file_writer(const std::string& name)
{
try
{
if (!m_file.open(fs::get_config_dir() + name, fs::rewrite + fs::append))
if (!m_file.open(fs::get_config_dir() + name, fs::read + fs::write + fs::create + fs::trunc + fs::unshare))
{
fmt::throw_exception("Can't create log file %s (error %s)", name, fs::g_tls_error);
}
#ifdef _WIN32
m_fmap = CreateFileMappingW(m_file.get_handle(), 0, PAGE_READWRITE, s_log_size >> 32, s_log_size & 0xffffffff, 0);
m_fptr = (uchar*)MapViewOfFile(m_fmap, FILE_MAP_WRITE, 0, 0, 0);
#else
m_fptr = (uchar*)::mmap(0, s_log_size, PROT_READ | PROT_WRITE, MAP_SHARED, m_file.get_handle(), 0);
#endif
}
catch (...)
{
@ -284,9 +302,29 @@ logs::file_writer::file_writer(const std::string& name)
}
}
logs::file_writer::~file_writer()
{
#ifdef _WIN32
UnmapViewOfFile(m_fptr);
CloseHandle(m_fmap);
m_file.seek(std::min(+m_pos, s_log_size));
SetEndOfFile(m_file.get_handle());
#else
::munmap(m_fptr, s_log_size);
m_file.trunc(std::min(+m_pos, s_log_size));
#endif
}
void logs::file_writer::log(const char* text, std::size_t size)
{
m_file.write(text, size);
// Acquire memory
const auto pos = m_pos.fetch_add(size);
// Write if possible
if (pos + size <= s_log_size)
{
std::memcpy(m_fptr + pos, text, size);
}
}
logs::file_listener::file_listener(const std::string& name)