From 8b934abcf21b75ba1fa38b8b6ec087b53dbb64f8 Mon Sep 17 00:00:00 2001 From: Eladash Date: Sat, 26 Nov 2022 12:01:55 +0200 Subject: [PATCH] Improve error_code, make HDD1 errors be warnings --- Utilities/Thread.cpp | 2 +- rpcs3/Emu/Cell/ErrorCodes.h | 51 ++++++++++++++++++++++++----------- rpcs3/Emu/Cell/lv2/sys_fs.cpp | 31 +++++++++++++++------ rpcs3/Emu/System.cpp | 19 ++++++++----- 4 files changed, 71 insertions(+), 32 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index bd7e265041..7498354d6b 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -2065,7 +2065,7 @@ void thread_base::set_name(std::string name) u64 thread_base::finalize(thread_state result_state) noexcept { // Report pending errors - error_code::error_report(0, 0, 0, 0); + error_code::error_report(0, nullptr, nullptr, nullptr, nullptr); #ifdef _WIN32 static thread_local ULONG64 tls_cycles{}; diff --git a/rpcs3/Emu/Cell/ErrorCodes.h b/rpcs3/Emu/Cell/ErrorCodes.h index 15e8a1fc3e..51b9f6a970 100644 --- a/rpcs3/Emu/Cell/ErrorCodes.h +++ b/rpcs3/Emu/Cell/ErrorCodes.h @@ -3,35 +3,54 @@ #include "util/types.hpp" #include "Utilities/StrFmt.h" +namespace logs +{ + struct message; +} + // Error code type (return type), implements error reporting. class error_code { s32 value; -public: - error_code() = default; - - // Implementation must be provided independently - static s32 error_report(s32 result, const char* fmt, const fmt_type_info* sup, const u64* args); - // Common constructor - template - error_code(const ET& value) - : value(error_report(static_cast(value), " : %s", fmt::type_info_v, fmt_args_t{fmt_unveil::get(value)})) + template requires requires (ET v) { static_cast(v); } + error_code(const logs::message* ch, const ET& value) noexcept + : value(error_report(static_cast(value), ch, " : %s", fmt::type_info_v, fmt_args_t{fmt_unveil::get(value)})) { } // Error constructor (2 args) - template - error_code(const ET& value, const T& arg) - : value(error_report(static_cast(value), " : %s, %s", fmt::type_info_v, fmt_args_t{fmt_unveil::get(value), fmt_unveil::get(arg)})) + template requires requires (ET v) { static_cast(v); } + error_code(const logs::message* ch, const ET& value, const T& arg) noexcept + : value(error_report(static_cast(value), ch, " : %s, %s", fmt::type_info_v, fmt_args_t{fmt_unveil::get(value), fmt_unveil::get(arg)})) { } // Formatting constructor (error, format string, variadic list) - template requires (sizeof...(Args) > 0) - error_code(const ET& value, const const_str& fmt, const Args&... args) - : value(error_report(static_cast(value), fmt, fmt::type_info_v, fmt_args_t{fmt_unveil::get(args)...})) + template requires requires (ET v) { static_cast(v); } + error_code(const logs::message* ch, const ET& value, const const_str& fmt, const Args&... args) noexcept + : value(error_report(static_cast(value), ch, fmt, fmt::type_info_v, fmt_args_t{fmt_unveil::get(args)...})) + { + } + +public: + // Implementation must be provided independently + static s32 error_report(s32 result, const logs::message* channel, const char* fmt, const fmt_type_info* sup, const u64* args); + + error_code() = default; + + // Constructor without channel + template requires (sizeof...(Args) > 0 && !(std::is_same_v>, logs::message> || ...)) + error_code(const Args&... args) noexcept + : error_code(std::add_pointer_t{}, args...) + { + } + + // Constructor with channel + template + error_code(const logs::message& ch, const Args&... args) noexcept + : error_code(std::addressof(ch), args...) { } @@ -51,7 +70,7 @@ enum CellNotAnError : s32 // Constructor specialization that doesn't trigger reporting template <> -constexpr FORCE_INLINE error_code::error_code(const CellNotAnError& value) +constexpr FORCE_INLINE error_code::error_code(const CellNotAnError& value) noexcept : value(value) { } diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.cpp b/rpcs3/Emu/Cell/lv2/sys_fs.cpp index ff533d5cb0..31e4973b72 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_fs.cpp @@ -945,7 +945,7 @@ error_code sys_fs_open(ppu_thread& ppu, vm::cptr path, s32 flags, vm::ptr< return not_an_error(CELL_EEXIST); } - return {error, path}; + return {lv2_fs_object::get_mp(vpath) == &g_mp_sys_dev_hdd1 ? sys_fs.warning : sys_fs.error, error, path}; } if (const u32 id = idm::import([&ppath = ppath, &file = file, mode, flags, &real = real, &type = type]() -> std::shared_ptr @@ -1246,7 +1246,7 @@ error_code sys_fs_opendir(ppu_thread& ppu, vm::cptr path, vm::ptr fd) { if (ext.empty()) { - return {CELL_ENOENT, path}; + return {mp == &g_mp_sys_dev_hdd1 ? sys_fs.warning : sys_fs.error, CELL_ENOENT, path}; } break; @@ -1435,7 +1435,7 @@ error_code sys_fs_stat(ppu_thread& ppu, vm::cptr path, vm::ptr break; } - return {CELL_ENOENT, path}; + return {mp == &g_mp_sys_dev_hdd1 ? sys_fs.warning : sys_fs.error, CELL_ENOENT, path}; } default: { @@ -1563,8 +1563,14 @@ error_code sys_fs_mkdir(ppu_thread& ppu, vm::cptr path, s32 mode) { switch (auto error = fs::g_tls_error) { - case fs::error::noent: return {CELL_ENOENT, path}; - case fs::error::exist: return {CELL_EEXIST, path}; + case fs::error::noent: + { + return {mp == &g_mp_sys_dev_hdd1 ? sys_fs.warning : sys_fs.error, CELL_ENOENT, path}; + } + case fs::error::exist: + { + return {sys_fs.warning, CELL_EEXIST, path}; + } default: sys_fs.error("sys_fs_mkdir(): unknown error %s", error); } @@ -1737,7 +1743,10 @@ error_code sys_fs_unlink(ppu_thread& ppu, vm::cptr path) { switch (auto error = fs::g_tls_error) { - case fs::error::noent: return {CELL_ENOENT, path}; + case fs::error::noent: + { + 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); } @@ -2690,7 +2699,10 @@ error_code sys_fs_truncate(ppu_thread& ppu, vm::cptr path, u64 size) { switch (auto error = fs::g_tls_error) { - case fs::error::noent: return {CELL_ENOENT, path}; + case fs::error::noent: + { + 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); } @@ -2890,7 +2902,10 @@ error_code sys_fs_utime(ppu_thread& ppu, vm::cptr path, vm::cptr g_tls_error_stats; static thread_local std::string g_tls_error_str; + static thread_local std::unordered_map g_tls_error_stats; + + if (!channel) + { + channel = &sys_log.error; + } if (!sup && !args) { @@ -2765,7 +2770,7 @@ s32 error_code::error_report(s32 result, const char* fmt, const fmt_type_info* s { if (pair.second > 3) { - sys_log.error("Stat: %s [x%u]", pair.first, pair.second); + channel->operator()("Stat: %s [x%u]", pair.first, pair.second); } } @@ -2776,7 +2781,6 @@ s32 error_code::error_report(s32 result, const char* fmt, const fmt_type_info* s ensure(fmt); - logs::channel* channel = &sys_log; const char* func = "Unknown function"; if (auto ppu = get_current_cpu_thread()) @@ -2789,6 +2793,7 @@ s32 error_code::error_report(s32 result, const char* fmt, const fmt_type_info* s // Format log message (use preallocated buffer) g_tls_error_str.clear(); + fmt::append(g_tls_error_str, "'%s' failed with 0x%08x", func, result); // Add spacer between error and fmt if necessary @@ -2804,10 +2809,10 @@ s32 error_code::error_report(s32 result, const char* fmt, const fmt_type_info* s if (!g_tls_error_stats.empty()) { // Report and clean error state - error_report(0, nullptr, nullptr, nullptr); + error_report(0, nullptr, nullptr, nullptr, nullptr); } - channel->error("%s", g_tls_error_str); + channel->operator()("%s", g_tls_error_str); } else { @@ -2815,7 +2820,7 @@ s32 error_code::error_report(s32 result, const char* fmt, const fmt_type_info* s if (stat <= 3) { - channel->error("%s [%u]", g_tls_error_str, stat); + channel->operator()("%s [%u]", g_tls_error_str, stat); } }