Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Utilities/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2816,6 +2816,16 @@ void thread_base::exec()
}
}

if (auto [total, current] = utils::get_memory_usage(); total - current <= 256 * 1024 * 1024)
{
if (reason_buf.empty())
{
reason_buf = std::string{reason};
}

fmt::append(reason_buf, " (Possible RAM deficiency: free RAM: %dMB)", (total - current) / (1024 * 1024));
}

if (!reason_buf.empty())
{
reason = reason_buf;
Expand Down
44 changes: 12 additions & 32 deletions rpcs3/Emu/Cell/lv2/sys_fs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -890,10 +890,8 @@ lv2_file::open_raw_result_t lv2_file::open_raw(const std::string& local_path, s3
switch (auto error = fs::g_tls_error)
{
case fs::error::noent: return {CELL_ENOENT};
default: sys_fs.error("lv2_file::open(): unknown error %s", error);
default: fmt::throw_exception("unknown error %s", error);
}

return {CELL_EIO};
}

if (flags & CELL_FS_O_MSELF && !verify_mself(file))
Expand Down Expand Up @@ -1364,8 +1362,7 @@ error_code sys_fs_opendir(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<u32> fd)
}
default:
{
sys_fs.error("sys_fs_opendir(): unknown error %s", error);
return {CELL_EIO, path};
fmt::throw_exception("unknown error %s", error);
}
}
}
Expand Down Expand Up @@ -1586,8 +1583,7 @@ error_code sys_fs_stat(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<CellFsStat>
}
default:
{
sys_fs.error("sys_fs_stat(): unknown error %s", error);
return {CELL_EIO, path};
fmt::throw_exception("unknown error %s", error);
}
}
}
Expand Down Expand Up @@ -1721,10 +1717,8 @@ error_code sys_fs_mkdir(ppu_thread& ppu, vm::cptr<char> path, s32 mode)
{
return {sys_fs.warning, CELL_EEXIST, path};
}
default: sys_fs.error("sys_fs_mkdir(): unknown error %s", error);
default: fmt::throw_exception("unknown error %s", error);
}

return {CELL_EIO, path}; // ???
}

sys_fs.notice("sys_fs_mkdir(): directory %s created", path);
Expand Down Expand Up @@ -1789,7 +1783,7 @@ error_code sys_fs_rename(ppu_thread& ppu, vm::cptr<char> from, vm::cptr<char> to
default: sys_fs.error("sys_fs_rename(): unknown error %s", error);
}

return {CELL_EIO, from}; // ???
fmt::throw_exception("unknown error %s", error);
}

sys_fs.notice("sys_fs_rename(): %s renamed to %s", from, to);
Expand Down Expand Up @@ -1841,10 +1835,8 @@ error_code sys_fs_rmdir(ppu_thread& ppu, vm::cptr<char> path)
{
case fs::error::noent: return {CELL_ENOENT, path};
case fs::error::notempty: return {CELL_ENOTEMPTY, path};
default: sys_fs.error("sys_fs_rmdir(): unknown error %s", error);
default: fmt::throw_exception("unknown error %s", error);
}

return {CELL_EIO, path}; // ???
}

sys_fs.notice("sys_fs_rmdir(): directory %s removed", path);
Expand Down Expand Up @@ -1899,10 +1891,8 @@ error_code sys_fs_unlink(ppu_thread& ppu, vm::cptr<char> path)
{
return {mp == &g_mp_sys_dev_hdd1 ? sys_fs.warning : sys_fs.error, CELL_ENOENT, path};
}
default: sys_fs.error("sys_fs_unlink(): unknown error %s", error);
default: fmt::throw_exception("unknown error %s", error);
}

return {CELL_EIO, path}; // ???
}

sys_fs.notice("sys_fs_unlink(): file %s deleted", path);
Expand Down Expand Up @@ -2620,10 +2610,8 @@ error_code sys_fs_lseek(ppu_thread& ppu, u32 fd, s64 offset, s32 whence, vm::ptr
switch (auto error = fs::g_tls_error)
{
case fs::error::inval: return {CELL_EINVAL, "fd=%u, offset=0x%x, whence=%d", fd, offset, whence};
default: sys_fs.error("sys_fs_lseek(): unknown error %s", error);
default: fmt::throw_exception("unknown error %s", error);
}

return CELL_EIO; // ???
}

lock.unlock();
Expand Down Expand Up @@ -2743,10 +2731,8 @@ error_code sys_fs_get_block_size(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<u
{
case fs::error::exist: return {CELL_EISDIR, path};
case fs::error::noent: return {CELL_ENOENT, path};
default: sys_fs.error("sys_fs_get_block_size(): unknown error %s", error);
default: fmt::throw_exception("unknown error %s", error);
}

return {CELL_EIO, path}; // ???
}

static_cast<void>(ppu.test_stopped());
Expand Down Expand Up @@ -2801,10 +2787,8 @@ error_code sys_fs_truncate(ppu_thread& ppu, vm::cptr<char> path, u64 size)
{
return {mp == &g_mp_sys_dev_hdd1 ? sys_fs.warning : sys_fs.error, CELL_ENOENT, path};
}
default: sys_fs.error("sys_fs_truncate(): unknown error %s", error);
default: fmt::throw_exception("unknown error %s", error);
}

return {CELL_EIO, path}; // ???
}

return CELL_OK;
Expand Down Expand Up @@ -2850,10 +2834,8 @@ error_code sys_fs_ftruncate(ppu_thread& ppu, u32 fd, u64 size)
switch (auto error = fs::g_tls_error)
{
case fs::error::ok:
default: sys_fs.error("sys_fs_ftruncate(): unknown error %s", error);
default: fmt::throw_exception("unknown error %s", error);
}

return CELL_EIO; // ???
}

return CELL_OK;
Expand Down Expand Up @@ -3057,10 +3039,8 @@ error_code sys_fs_utime(ppu_thread& ppu, vm::cptr<char> path, vm::cptr<CellFsUti
{
return {mp == &g_mp_sys_dev_hdd1 ? sys_fs.warning : sys_fs.error, CELL_ENOENT, path};
}
default: sys_fs.error("sys_fs_utime(): unknown error %s", error);
default: fmt::throw_exception("unknown error %s", error);
}

return {CELL_EIO, path}; // ???
}

return CELL_OK;
Expand Down
23 changes: 15 additions & 8 deletions rpcs3/Emu/perf_monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
#include "Emu/System.h"
#include "Emu/Cell/timers.hpp"
#include "util/cpu_stats.hpp"
#include "util/sysinfo.hpp"
#include "Utilities/Thread.h"

LOG_CHANNEL(perf_log, "PERF");

void perf_monitor::operator()()
{
constexpr u64 update_interval_us = 1000000; // Update every second
constexpr u64 update_interval_us = 500000; // Update every half second
constexpr u64 log_interval_us = 10000000; // Log every 10 seconds
u64 elapsed_us = 0;

Expand All @@ -19,25 +20,24 @@ void perf_monitor::operator()()

u32 logged_pause = 0;
u64 last_pause_time = umax;
u64 max_memory_usage = 0;

std::vector<double> per_core_usage;
std::string msg;

for (u64 sleep_until = get_system_time(); thread_ctrl::state() != thread_state::aborting;)
for (u64 sleep_until = get_system_time();;)
{
thread_ctrl::wait_until(&sleep_until, update_interval_us);
elapsed_us += update_interval_us;

if (thread_ctrl::state() == thread_state::aborting)
{
break;
}

double total_usage = 0.0;

stats.get_per_core_usage(per_core_usage, total_usage);

if (elapsed_us >= log_interval_us)
const u64 current_mem_use = utils::get_memory_usage().second;
max_memory_usage = std::max<u64>(current_mem_use, max_memory_usage);

if (elapsed_us >= log_interval_us || thread_ctrl::state() == thread_state::aborting)
{
elapsed_us = 0;

Expand Down Expand Up @@ -76,7 +76,14 @@ void perf_monitor::operator()()
fmt::append(msg, "%s %.1f%%", i > 0 ? "," : "", per_core_usage[i]);
}

fmt::append(msg, ", RAM Usage: %dMB (Peak: %dMB)", current_mem_use / (1024 * 1024), max_memory_usage / (1024 * 1024));
perf_log.notice("%s", msg);

if (thread_ctrl::state() == thread_state::aborting)
{
// Log once before terminating
break;
}
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions rpcs3/rpcs3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@ std::set<std::string> get_one_drive_paths()

fmt::append(buf, "\nBuild: \"%s\"", rpcs3::get_verbose_version());
fmt::append(buf, "\nDate: \"%s\"", std::chrono::system_clock::now());

const auto [total, current] = utils::get_memory_usage();

fmt::append(buf, "\nRAM Usage: %dMB/%dMB (%dMB free)", current / (1024 * 1024), total / (1024 * 1024), (total - current) / (1024 * 1024));
}

std::string_view text = s_is_error_launch ? _text : buf;
Expand Down
16 changes: 15 additions & 1 deletion rpcs3/util/sysinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,20 @@ std::string utils::get_firmware_version()
return {};
}

std::pair<u64, u64> utils::get_memory_usage()
{
#ifdef _WIN32
::MEMORYSTATUSEX status{};
status.dwLength = sizeof(status);
::GlobalMemoryStatusEx(&status);
return { status.ullTotalPhys, status.ullAvailPhys };

#else
// TODO
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing other OS implementations, just to keep in mind

return { get_total_memory(), 0 };
#endif
}

utils::OS_version utils::get_OS_version()
{
OS_version res {};
Expand Down Expand Up @@ -972,7 +986,7 @@ static const bool s_tsc_freq_evaluated = []() -> bool
u64 utils::get_total_memory()
{
#ifdef _WIN32
::MEMORYSTATUSEX memInfo;
::MEMORYSTATUSEX memInfo{};
memInfo.dwLength = sizeof(memInfo);
::GlobalMemoryStatusEx(&memInfo);
return memInfo.ullTotalPhys;
Expand Down
2 changes: 2 additions & 0 deletions rpcs3/util/sysinfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ namespace utils

std::string get_firmware_version();

std::pair<u64, u64> get_memory_usage();

struct OS_version
{
std::string type;
Expand Down
Loading