mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-12-06 07:12:14 +01:00
android: add affinity support with config
add aarch64 get_cpu_name teach cfg::try_to_enum_value and cfg::try_to_enum_list ignore gaps
This commit is contained in:
parent
1585817013
commit
6ad58c8813
|
|
@ -226,6 +226,7 @@ bool try_to_string(std::string* out, const f64& value)
|
||||||
bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, std::string_view value)
|
bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) func, std::string_view value)
|
||||||
{
|
{
|
||||||
u64 max = umax;
|
u64 max = umax;
|
||||||
|
std::size_t gap = 0;
|
||||||
|
|
||||||
for (u64 i = 0;; i++)
|
for (u64 i = 0;; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -241,10 +242,16 @@ bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) f
|
||||||
std::string hex;
|
std::string hex;
|
||||||
fmt_class_string<u64>::format(hex, i);
|
fmt_class_string<u64>::format(hex, i);
|
||||||
if (var == hex)
|
if (var == hex)
|
||||||
|
{
|
||||||
|
if (++gap > 100)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
gap = 0;
|
||||||
max = i;
|
max = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -281,6 +288,7 @@ bool cfg::try_to_enum_value(u64* out, decltype(&fmt_class_string<int>::format) f
|
||||||
std::vector<std::string> cfg::try_to_enum_list(decltype(&fmt_class_string<int>::format) func)
|
std::vector<std::string> cfg::try_to_enum_list(decltype(&fmt_class_string<int>::format) func)
|
||||||
{
|
{
|
||||||
std::vector<std::string> result;
|
std::vector<std::string> result;
|
||||||
|
std::size_t gap = 0;
|
||||||
|
|
||||||
for (u64 i = 0;; i++)
|
for (u64 i = 0;; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -290,10 +298,17 @@ std::vector<std::string> cfg::try_to_enum_list(decltype(&fmt_class_string<int>::
|
||||||
std::string hex;
|
std::string hex;
|
||||||
fmt_class_string<u64>::format(hex, i);
|
fmt_class_string<u64>::format(hex, i);
|
||||||
if (var == hex)
|
if (var == hex)
|
||||||
|
{
|
||||||
|
if (++gap > 100)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
gap = 0;
|
||||||
|
|
||||||
result.emplace_back(std::move(var));
|
result.emplace_back(std::move(var));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,22 @@ extern thread_local std::string(*g_tls_log_prefix)();
|
||||||
|
|
||||||
enum cpu_threads_emulation_info_dump_t : u32 {};
|
enum cpu_threads_emulation_info_dump_t : u32 {};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void fmt_class_string<thread_class>::format(std::string& out, u64 arg)
|
||||||
|
{
|
||||||
|
format_enum(out, arg, [](thread_class value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case thread_class::general: return "General";
|
||||||
|
case thread_class::ppu: return "PPU";
|
||||||
|
case thread_class::spu: return "SPU";
|
||||||
|
case thread_class::rsx: return "RSX";
|
||||||
|
}
|
||||||
|
return unknown;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
std::string dump_useful_thread_info()
|
std::string dump_useful_thread_info()
|
||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
|
|
@ -2926,6 +2942,28 @@ void thread_ctrl::detect_cpu_layout()
|
||||||
|
|
||||||
u64 thread_ctrl::get_affinity_mask(thread_class group)
|
u64 thread_ctrl::get_affinity_mask(thread_class group)
|
||||||
{
|
{
|
||||||
|
#ifdef ANDROID
|
||||||
|
u64 mask = 0;
|
||||||
|
thread_class affinities[] = {
|
||||||
|
g_cfg.core.affinity.cpu0.get(),
|
||||||
|
g_cfg.core.affinity.cpu1.get(),
|
||||||
|
g_cfg.core.affinity.cpu2.get(),
|
||||||
|
g_cfg.core.affinity.cpu3.get(),
|
||||||
|
g_cfg.core.affinity.cpu4.get(),
|
||||||
|
g_cfg.core.affinity.cpu5.get(),
|
||||||
|
g_cfg.core.affinity.cpu6.get(),
|
||||||
|
g_cfg.core.affinity.cpu7.get()
|
||||||
|
};
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < std::size(affinities); ++i) {
|
||||||
|
if (affinities[i] == group || affinities[i] == thread_class::general) {
|
||||||
|
mask |= 1ull < i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mask;
|
||||||
|
#endif
|
||||||
|
|
||||||
detect_cpu_layout();
|
detect_cpu_layout();
|
||||||
|
|
||||||
if (const auto thread_count = utils::get_thread_count())
|
if (const auto thread_count = utils::get_thread_count())
|
||||||
|
|
@ -3205,7 +3243,7 @@ void thread_ctrl::set_thread_affinity_mask(u64 mask)
|
||||||
thread_affinity_policy_data_t policy = { static_cast<integer_t>(std::countr_zero(mask)) };
|
thread_affinity_policy_data_t policy = { static_cast<integer_t>(std::countr_zero(mask)) };
|
||||||
thread_port_t mach_thread = pthread_mach_thread_np(pthread_self());
|
thread_port_t mach_thread = pthread_mach_thread_np(pthread_self());
|
||||||
thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, reinterpret_cast<thread_policy_t>(&policy), !mask ? 0 : 1);
|
thread_policy_set(mach_thread, THREAD_AFFINITY_POLICY, reinterpret_cast<thread_policy_t>(&policy), !mask ? 0 : 1);
|
||||||
#elif !defined(ANDROID) && (defined(__linux__) || defined(__DragonFly__) || defined(__FreeBSD__))
|
#elif (defined(__linux__) || defined(__DragonFly__) || defined(__FreeBSD__))
|
||||||
if (!mask)
|
if (!mask)
|
||||||
{
|
{
|
||||||
// Reset affinity mask
|
// Reset affinity mask
|
||||||
|
|
@ -3232,8 +3270,11 @@ void thread_ctrl::set_thread_affinity_mask(u64 mask)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef ANDROID
|
||||||
|
if (int err = sched_setaffinity(::gettid(), sizeof(cpu_set_t), &cs))
|
||||||
|
#else
|
||||||
if (int err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cs))
|
if (int err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cs))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
sig_log.error("Failed to set thread affinity 0x%x: error %d.", mask, err);
|
sig_log.error("Failed to set thread affinity 0x%x: error %d.", mask, err);
|
||||||
}
|
}
|
||||||
|
|
@ -3257,11 +3298,15 @@ u64 thread_ctrl::get_thread_affinity_mask()
|
||||||
|
|
||||||
sig_log.error("Failed to get thread affinity mask.");
|
sig_log.error("Failed to get thread affinity mask.");
|
||||||
return 0;
|
return 0;
|
||||||
#elif !defined(ANDROID) && (defined(__linux__) || defined(__DragonFly__) || defined(__FreeBSD__))
|
#elif (defined(__linux__) || defined(__DragonFly__) || defined(__FreeBSD__))
|
||||||
cpu_set_t cs;
|
cpu_set_t cs;
|
||||||
CPU_ZERO(&cs);
|
CPU_ZERO(&cs);
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
if (int err = sched_getaffinity(::gettid(), sizeof(cpu_set_t), &cs))
|
||||||
|
#else
|
||||||
if (int err = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cs))
|
if (int err = pthread_getaffinity_np(pthread_self(), sizeof(cpu_set_t), &cs))
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
sig_log.error("Failed to get thread affinity mask: error %d.", err);
|
sig_log.error("Failed to get thread affinity mask: error %d.", err);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -246,6 +246,16 @@ namespace aarch64
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *get_cpu_name(int cpu)
|
||||||
|
{
|
||||||
|
const auto midr = read_MIDR_EL1(cpu);
|
||||||
|
const auto implementer_id = (midr >> 24) & 0xff;
|
||||||
|
const auto part_id = (midr >> 4) & 0xfff;
|
||||||
|
|
||||||
|
const auto part_info = find_cpu_part(implementer_id, part_id);
|
||||||
|
return part_info ? part_info->name : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
std::string get_cpu_name()
|
std::string get_cpu_name()
|
||||||
{
|
{
|
||||||
std::map<u64, int> core_layout;
|
std::map<u64, int> core_layout;
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ namespace aarch64
|
||||||
"xzr", ".", "sp"
|
"xzr", ".", "sp"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const char *get_cpu_name(int cpu);
|
||||||
std::string get_cpu_name();
|
std::string get_cpu_name();
|
||||||
std::string get_cpu_brand();
|
std::string get_cpu_brand();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Utilities/Thread.h"
|
||||||
#include "system_config_types.h"
|
#include "system_config_types.h"
|
||||||
#include "Utilities/Config.h"
|
#include "Utilities/Config.h"
|
||||||
|
|
||||||
|
|
@ -46,6 +47,22 @@ struct cfg_root : cfg::node
|
||||||
cfg::_bool accurate_cache_line_stores{ this, "Accurate Cache Line Stores", false };
|
cfg::_bool accurate_cache_line_stores{ this, "Accurate Cache Line Stores", false };
|
||||||
cfg::_bool rsx_accurate_res_access{this, "Accurate RSX reservation access", false, true};
|
cfg::_bool rsx_accurate_res_access{this, "Accurate RSX reservation access", false, true};
|
||||||
|
|
||||||
|
#ifdef ANDROID
|
||||||
|
struct node_affinity : cfg::node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
node_affinity(cfg::node* _this) : cfg::node(_this, "Affinity") {}
|
||||||
|
cfg::_enum<thread_class> cpu0{this, "CPU0", thread_class::general, true};
|
||||||
|
cfg::_enum<thread_class> cpu1{this, "CPU1", thread_class::general, true};
|
||||||
|
cfg::_enum<thread_class> cpu2{this, "CPU2", thread_class::general, true};
|
||||||
|
cfg::_enum<thread_class> cpu3{this, "CPU3", thread_class::general, true};
|
||||||
|
cfg::_enum<thread_class> cpu4{this, "CPU4", thread_class::general, true};
|
||||||
|
cfg::_enum<thread_class> cpu5{this, "CPU5", thread_class::general, true};
|
||||||
|
cfg::_enum<thread_class> cpu6{this, "CPU6", thread_class::general, true};
|
||||||
|
cfg::_enum<thread_class> cpu7{this, "CPU7", thread_class::general, true};
|
||||||
|
} affinity { this };
|
||||||
|
#endif
|
||||||
|
|
||||||
struct fifo_setting : public cfg::_enum<rsx_fifo_mode>
|
struct fifo_setting : public cfg::_enum<rsx_fifo_mode>
|
||||||
{
|
{
|
||||||
using _enum = cfg::_enum<rsx_fifo_mode>;
|
using _enum = cfg::_enum<rsx_fifo_mode>;
|
||||||
|
|
|
||||||
|
|
@ -197,8 +197,7 @@ namespace utils
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif __linux__
|
#elif __linux__ && !defined(ANDROID)
|
||||||
#ifndef ANDROID
|
|
||||||
m_previous_idle_times_per_cpu.resize(utils::get_thread_count(), 0.0);
|
m_previous_idle_times_per_cpu.resize(utils::get_thread_count(), 0.0);
|
||||||
m_previous_total_times_per_cpu.resize(utils::get_thread_count(), 0.0);
|
m_previous_total_times_per_cpu.resize(utils::get_thread_count(), 0.0);
|
||||||
|
|
||||||
|
|
@ -289,7 +288,6 @@ namespace utils
|
||||||
{
|
{
|
||||||
perf_log.error("Failed to open /proc/stat (%s)", strerror(errno));
|
perf_log.error("Failed to open /proc/stat (%s)", strerror(errno));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
total_usage = get_usage();
|
total_usage = get_usage();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue