Skip to content

Commit

Permalink
Improve error_code, make HDD1 errors be warnings
Browse files Browse the repository at this point in the history
  • Loading branch information
elad335 committed Nov 26, 2022
1 parent fa74d3e commit 267cd4e
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 30 deletions.
2 changes: 1 addition & 1 deletion Utilities/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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::make_report(0, false, 0, 0, 0);

#ifdef _WIN32
static thread_local ULONG64 tls_cycles{};
Expand Down
37 changes: 26 additions & 11 deletions rpcs3/Emu/Cell/ErrorCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
#include "util/types.hpp"
#include "Utilities/StrFmt.h"

struct error_is_warning
{
bool value = true;
};

// Error code type (return type), implements error reporting.
class error_code
{
Expand All @@ -12,26 +17,35 @@ class error_code
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);
static s32 make_report(s32 result, bool is_warning, const char* fmt, const fmt_type_info* sup, const u64* args);
static void log_report();
bool silence_report();

// Common constructor
template<typename ET>
error_code(const ET& value)
: value(error_report(static_cast<s32>(value), " : %s", fmt::type_info_v<ET>, fmt_args_t<ET>{fmt_unveil<ET>::get(value)}))
template <typename ET> requires requires (ET v) { static_cast<s32>(v); }
error_code(error_is_warning is_warning, const ET& value) noexcept
: value(make_report(static_cast<s32>(value), is_warning.value, " : %s", fmt::type_info_v<ET>, fmt_args_t<ET>{fmt_unveil<ET>::get(value)}))
{
}

// Error constructor (2 args)
template<typename ET, typename T>
error_code(const ET& value, const T& arg)
: value(error_report(static_cast<s32>(value), " : %s, %s", fmt::type_info_v<ET, T>, fmt_args_t<ET, T>{fmt_unveil<ET>::get(value), fmt_unveil<T>::get(arg)}))
template<typename ET, typename T> requires requires (ET v) { static_cast<s32>(v); }
error_code(error_is_warning is_warning, const ET& value, const T& arg) noexcept
: value(make_report(static_cast<s32>(value), is_warning.value, " : %s, %s", fmt::type_info_v<ET, t>, fmt_args_t<ET, t>{fmt_unveil<ET>::get(value), fmt_unveil<t>::get(std::forward<T>(arg))}))
{
}

// Formatting constructor (error, format string, variadic list)
template <typename ET, typename... Args> requires (sizeof...(Args) > 0)
error_code(const ET& value, const const_str& fmt, const Args&... args)
: value(error_report(static_cast<s32>(value), fmt, fmt::type_info_v<Args...>, fmt_args_t<Args...>{fmt_unveil<Args>::get(args)...}))
template <typename ET, typename... Args> requires (sizeof...(Args) > 0) && (requires (ET v) { static_cast<s32>(v); })
error_code(error_is_warning is_warning, const ET& value, const const_str& fmt, const Args&... args) noexcept
: value(make_report(static_cast<s32>(value), is_warning.value, fmt, fmt::type_info_v<Args...>, fmt_args_t<Args...>{fmt_unveil<Args>::get(std::forward<Args>(args))...}))
{
}

// Not a warning constructor
template <typename... Args> requires (!(std::is_same_v<std::remove_cvref_t<Args>, error_is_warning> || ...))
error_code(Args&&... args) noexcept
: error_code({false}, std::forward<Args>(args)...)
{
}

Expand All @@ -51,7 +65,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(CellNotAnError&& value)
: value(value)
{
}
Expand All @@ -71,6 +85,7 @@ struct ppu_gpr_cast_impl<error_code, void>
{
static inline u64 to(const error_code& code)
{
error_code::log_report();
return code;
}

Expand Down
31 changes: 23 additions & 8 deletions rpcs3/Emu/Cell/lv2/sys_fs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -945,7 +945,7 @@ error_code sys_fs_open(ppu_thread& ppu, vm::cptr<char> path, s32 flags, vm::ptr<
return not_an_error(CELL_EEXIST);
}

return {error, path};
return {error_is_warning{lv2_fs_object::get_mp(vpath) == &g_mp_sys_dev_hdd1}, error, path};
}

if (const u32 id = idm::import<lv2_fs_object, lv2_file>([&ppath = ppath, &file = file, mode, flags, &real = real, &type = type]() -> std::shared_ptr<lv2_file>
Expand Down Expand Up @@ -1246,7 +1246,7 @@ error_code sys_fs_opendir(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<u32> fd)
{
if (ext.empty())
{
return {CELL_ENOENT, path};
return {error_is_warning{mp == &g_mp_sys_dev_hdd1}, CELL_ENOENT, path};
}

break;
Expand Down Expand Up @@ -1435,7 +1435,7 @@ error_code sys_fs_stat(ppu_thread& ppu, vm::cptr<char> path, vm::ptr<CellFsStat>
break;
}

return {CELL_ENOENT, path};
return {error_is_warning{mp == &g_mp_sys_dev_hdd1}, CELL_ENOENT, path};
}
default:
{
Expand Down Expand Up @@ -1563,8 +1563,14 @@ error_code sys_fs_mkdir(ppu_thread& ppu, vm::cptr<char> 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 {error_is_warning{mp == &g_mp_sys_dev_hdd1}, CELL_ENOENT, path};
}
case fs::error::exist:
{
return {error_is_warning{}, CELL_EEXIST, path};
}
default: sys_fs.error("sys_fs_mkdir(): unknown error %s", error);
}

Expand Down Expand Up @@ -1737,7 +1743,10 @@ error_code sys_fs_unlink(ppu_thread& ppu, vm::cptr<char> path)
{
switch (auto error = fs::g_tls_error)
{
case fs::error::noent: return {CELL_ENOENT, path};
case fs::error::noent:
{
return {error_is_warning{mp == &g_mp_sys_dev_hdd1}, CELL_ENOENT, path};
}
default: sys_fs.error("sys_fs_unlink(): unknown error %s", error);
}

Expand Down Expand Up @@ -2690,7 +2699,10 @@ error_code sys_fs_truncate(ppu_thread& ppu, vm::cptr<char> path, u64 size)
{
switch (auto error = fs::g_tls_error)
{
case fs::error::noent: return {CELL_ENOENT, path};
case fs::error::noent:
{
return {error_is_warning{mp == &g_mp_sys_dev_hdd1}, CELL_ENOENT, path};
}
default: sys_fs.error("sys_fs_truncate(): unknown error %s", error);
}

Expand Down Expand Up @@ -2890,7 +2902,10 @@ error_code sys_fs_utime(ppu_thread& ppu, vm::cptr<char> path, vm::cptr<CellFsUti
{
switch (auto error = fs::g_tls_error)
{
case fs::error::noent: return {CELL_ENOENT, path};
case fs::error::noent:
{
return {error_is_warning{mp == &g_mp_sys_dev_hdd1}, CELL_ENOENT, path};
}
default: sys_fs.error("sys_fs_utime(): unknown error %s", error);
}

Expand Down
45 changes: 35 additions & 10 deletions rpcs3/Emu/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2751,11 +2751,12 @@ std::string Emulator::GetFormattedTitle(double fps) const
return rpcs3::get_formatted_title(title_data);
}

s32 error_code::error_report(s32 result, const char* fmt, const fmt_type_info* sup, const u64* args)
{
static thread_local std::unordered_map<std::string, usz> g_tls_error_stats;
static thread_local std::string g_tls_error_str;
static thread_local std::string g_tls_error_str;
static thread_local std::unordered_map<std::string, usz> g_tls_error_stats;
static thread_local bool g_tls_is_error_a_warning;

s32 error_code::make_report(s32 result, bool is_warning, const char* fmt, const fmt_type_info* sup, const u64* args)
{
if (!sup && !args)
{
if (!fmt)
Expand All @@ -2776,7 +2777,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<ppu_thread>())
Expand All @@ -2789,6 +2789,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();
g_tls_is_error_a_warning = is_warning;
fmt::append(g_tls_error_str, "'%s' failed with 0x%08x", func, result);

// Add spacer between error and fmt if necessary
Expand All @@ -2804,24 +2805,48 @@ 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);
make_report(0, false, nullptr, nullptr, nullptr);
}

channel->error("%s", g_tls_error_str);
}
else
{
const auto stat = ++g_tls_error_stats[g_tls_error_str];

if (stat <= 3)
if (stat > 3)
{
channel->error("%s [%u]", g_tls_error_str, stat);
g_tls_error_str.clear();
}
}

return result;
}

void error_code::log_report()
{
const bool is_warning = std::exchange(g_tls_is_error_a_warning, false);

if (g_tls_error_str.empty())
{
// No error
return;
}

(is_warning ? sys_log.warning : sys_log.error)("%s", g_tls_error_str);
g_tls_error_str.clear();
}

bool error_code::silence_report()
{
if (!g_tls_error_str.empty() && g_tls_error_str.ends_with(fmt::format("0x%08x", value)))
{
g_tls_error_str.clear();
g_tls_is_error_a_warning = false;
return true;
}

return false;
}

void Emulator::ConfigurePPUCache() const
{
auto& _main = g_fxo->get<ppu_module>();
Expand Down

0 comments on commit 267cd4e

Please sign in to comment.