diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index af7dddc96d..1f80dc3915 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -787,6 +787,29 @@ void Emulator::Stop() s32 error_code::error_report(const fmt_type_info* sup, u64 arg) { + static thread_local std::unordered_map* g_tls_error_stats{}; + static thread_local std::string* g_tls_error_str{}; + + if (!g_tls_error_stats) + { + g_tls_error_stats = new std::unordered_map; + g_tls_error_str = new std::string; + + thread_ctrl::atexit([] + { + for (auto&& pair : *g_tls_error_stats) + { + if (pair.second > 3) + { + LOG_ERROR(GENERAL, "Stat: %s [x%u]", pair.first, pair.second); + } + } + + delete g_tls_error_stats; + delete g_tls_error_str; + }); + } + logs::channel* channel = &logs::GENERAL; logs::level level = logs::level::error; const char* func = "Unknown function"; @@ -797,29 +820,6 @@ s32 error_code::error_report(const fmt_type_info* sup, u64 arg) { auto& ppu = static_cast(*thread); - // Filter some annoying reports - switch (arg) - { - case CELL_ESRCH: - case CELL_EDEADLK: - case CELL_EPERM: - { - if (ppu.m_name == "_cellsurMixerMain" || ppu.m_name == "_sys_MixerChStripMain") - { - if (std::memcmp(ppu.last_function, "sys_mutex_lock", 15) == 0 || - std::memcmp(ppu.last_function, "sys_lwmutex_lock", 17) == 0 || - std::memcmp(ppu.last_function, "_sys_mutex_lock", 16) == 0 || - std::memcmp(ppu.last_function, "_sys_lwmutex_lock", 18) == 0 || - std::memcmp(ppu.last_function, "sys_lwmutex_unlock", 19) == 0) - { - level = logs::level::trace; - } - } - - break; - } - } - if (ppu.last_function) { func = ppu.last_function; @@ -835,7 +835,18 @@ s32 error_code::error_report(const fmt_type_info* sup, u64 arg) } } - channel->format(level, "'%s' failed with 0x%08x%s%s", func, arg, sup ? " : " : "", std::make_pair(sup, arg)); + // Format log message (use preallocated buffer) + g_tls_error_str->clear(); + fmt::append(*g_tls_error_str, "'%s' failed with 0x%08x%s%s", func, arg, sup ? " : " : "", std::make_pair(sup, arg)); + + // Update stats and check log threshold + const auto stat = ++(*g_tls_error_stats)[*g_tls_error_str]; + + if (stat <= 3) + { + channel->format(level, "%s [%u]", *g_tls_error_str, stat); + } + return static_cast(arg); }