mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-06 23:15:18 +00:00
Move CPUStats.h -> util/cpu_stats.cpp
This commit is contained in:
parent
090a769bf6
commit
cd01a1eb09
7 changed files with 57 additions and 43 deletions
|
|
@ -40,6 +40,7 @@ target_sources(rpcs3_emu PRIVATE
|
|||
../util/vm_native.cpp
|
||||
../util/dyn_lib.cpp
|
||||
../util/sysinfo.cpp
|
||||
../util/cpu_stats.cpp
|
||||
../../Utilities/bin_patch.cpp
|
||||
../../Utilities/cheat_info.cpp
|
||||
../../Utilities/cond.cpp
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
#include <charconv>
|
||||
|
||||
#include "util/sysinfo.hpp"
|
||||
#include "util/cpu_stats.hpp"
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
|
|
@ -423,7 +424,7 @@ namespace rsx
|
|||
|
||||
m_rsx_load = rsx_thread->get_load();
|
||||
|
||||
m_total_threads = CPUStats::get_thread_count();
|
||||
m_total_threads = utils::cpu_stats::get_thread_count();
|
||||
|
||||
[[fallthrough]];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "overlays.h"
|
||||
#include "Utilities/CPUStats.h"
|
||||
#include "util/cpu_stats.hpp"
|
||||
#include "Emu/system_config_types.h"
|
||||
|
||||
namespace rsx
|
||||
|
|
@ -28,7 +28,7 @@ namespace rsx
|
|||
graph m_fps_graph;
|
||||
graph m_frametime_graph;
|
||||
|
||||
CPUStats m_cpu_stats{};
|
||||
utils::cpu_stats m_cpu_stats{};
|
||||
Timer m_update_timer{};
|
||||
Timer m_frametime_timer{};
|
||||
u32 m_update_interval{}; // in ms
|
||||
|
|
|
|||
|
|
@ -149,6 +149,9 @@
|
|||
<ClCompile Include="util\sysinfo.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="util\cpu_stats.cpp">
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\Utilities\Thread.cpp" />
|
||||
<ClCompile Include="..\Utilities\version.cpp" />
|
||||
<ClCompile Include="util\vm_native.cpp" />
|
||||
|
|
@ -508,6 +511,7 @@
|
|||
<ClInclude Include="util\slow_mutex.hpp" />
|
||||
<ClInclude Include="util\fifo_mutex.hpp" />
|
||||
<ClInclude Include="util\logs.hpp" />
|
||||
<ClInclude Include="util\cpu_stats.hpp" />
|
||||
<ClInclude Include="..\Utilities\dyn_lib.hpp" />
|
||||
<ClInclude Include="..\Utilities\File.h" />
|
||||
<ClInclude Include="..\Utilities\Config.h" />
|
||||
|
|
|
|||
|
|
@ -884,6 +884,9 @@
|
|||
<ClCompile Include="util\fixed_typemap.cpp">
|
||||
<Filter>Utilities</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="util\cpu_stats.cpp">
|
||||
<Filter>Utilities</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Crypto\aesni.cpp">
|
||||
<Filter>Crypto</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -973,12 +976,12 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="Emu\Io\interception.cpp">
|
||||
<Filter>Emu\Io</Filter>
|
||||
</ClCompile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\RSX\RSXDisAsm.cpp">
|
||||
<Filter>Emu\GPU\RSX</Filter>
|
||||
</ClCompile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Emu\RSX\Common\texture_cache.cpp">
|
||||
<Filter>Emu\GPU\RSX\Common</Filter>
|
||||
<Filter>Emu\GPU\RSX\Common</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
@ -1855,6 +1858,9 @@
|
|||
<ClInclude Include="util\typeindices.hpp">
|
||||
<Filter>Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="util\cpu_stats.hpp">
|
||||
<Filter>Utilities</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\Common\ShaderInterpreter.h">
|
||||
<Filter>Emu\GPU\RSX\Common</Filter>
|
||||
</ClInclude>
|
||||
|
|
@ -1901,14 +1907,14 @@
|
|||
<Filter>Emu\GPU\RSX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Utilities\dyn_lib.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\RSXDisAsm.h">
|
||||
<Filter>Emu\GPU\RSX</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Emu\RSX\Common\texture_cache_types.h">
|
||||
<Filter>Emu\GPU\RSX\Common</Filter>
|
||||
</ClInclude>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Emu\RSX\Common\Interpreter\FragmentInterpreter.glsl">
|
||||
|
|
|
|||
227
rpcs3/util/cpu_stats.cpp
Normal file
227
rpcs3/util/cpu_stats.cpp
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
#include "util/types.hpp"
|
||||
#include "util/cpu_stats.hpp"
|
||||
#include "util/sysinfo.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "windows.h"
|
||||
#include "tlhelp32.h"
|
||||
#else
|
||||
#include "stdlib.h"
|
||||
#include "sys/times.h"
|
||||
#include "sys/types.h"
|
||||
#include "unistd.h"
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
# include <mach/mach_init.h>
|
||||
# include <mach/task.h>
|
||||
# include <mach/vm_map.h>
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
# include <dirent.h>
|
||||
#endif
|
||||
|
||||
#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
# include <sys/sysctl.h>
|
||||
# if defined(__DragonFly__) || defined(__FreeBSD__)
|
||||
# include <sys/user.h>
|
||||
# endif
|
||||
|
||||
# if defined(__NetBSD__)
|
||||
# undef KERN_PROC
|
||||
# define KERN_PROC KERN_PROC2
|
||||
# define kinfo_proc kinfo_proc2
|
||||
# endif
|
||||
|
||||
# if defined(__DragonFly__)
|
||||
# define KP_NLWP(kp) (kp.kp_nthreads)
|
||||
# elif defined(__FreeBSD__)
|
||||
# define KP_NLWP(kp) (kp.ki_numthreads)
|
||||
# elif defined(__NetBSD__)
|
||||
# define KP_NLWP(kp) (kp.p_nlwps)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace utils
|
||||
{
|
||||
cpu_stats::cpu_stats()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SYSTEM_INFO sysInfo;
|
||||
FILETIME ftime, fsys, fuser;
|
||||
|
||||
GetSystemTimeAsFileTime(&ftime);
|
||||
memcpy(&m_last_cpu, &ftime, sizeof(FILETIME));
|
||||
|
||||
GetProcessTimes(GetCurrentProcess(), &ftime, &ftime, &fsys, &fuser);
|
||||
memcpy(&m_sys_cpu, &fsys, sizeof(FILETIME));
|
||||
memcpy(&m_usr_cpu, &fuser, sizeof(FILETIME));
|
||||
#else
|
||||
struct tms timeSample;
|
||||
|
||||
m_last_cpu = times(&timeSample);
|
||||
m_sys_cpu = timeSample.tms_stime;
|
||||
m_usr_cpu = timeSample.tms_utime;
|
||||
#endif
|
||||
}
|
||||
|
||||
double cpu_stats::get_usage()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
FILETIME ftime, fsys, fusr;
|
||||
ULARGE_INTEGER now, sys, usr;
|
||||
|
||||
GetSystemTimeAsFileTime(&ftime);
|
||||
memcpy(&now, &ftime, sizeof(FILETIME));
|
||||
|
||||
GetProcessTimes(GetCurrentProcess(), &ftime, &ftime, &fsys, &fusr);
|
||||
memcpy(&sys, &fsys, sizeof(FILETIME));
|
||||
memcpy(&usr, &fusr, sizeof(FILETIME));
|
||||
double percent = 1. * (sys.QuadPart - m_sys_cpu) + (usr.QuadPart - m_usr_cpu);
|
||||
percent /= (now.QuadPart - m_last_cpu);
|
||||
percent /= utils::get_thread_count();
|
||||
|
||||
m_last_cpu = now.QuadPart;
|
||||
m_usr_cpu = usr.QuadPart;
|
||||
m_sys_cpu = sys.QuadPart;
|
||||
|
||||
return std::clamp(percent * 100, 0.0, 100.0);
|
||||
#else
|
||||
struct tms timeSample;
|
||||
clock_t now;
|
||||
double percent;
|
||||
|
||||
now = times(&timeSample);
|
||||
if (now <= static_cast<clock_t>(m_last_cpu) || timeSample.tms_stime < static_cast<clock_t>(m_sys_cpu) || timeSample.tms_utime < static_cast<clock_t>(m_usr_cpu))
|
||||
{
|
||||
// Overflow detection. Just skip this value.
|
||||
percent = -1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
percent = (timeSample.tms_stime - m_sys_cpu) + (timeSample.tms_utime - m_usr_cpu);
|
||||
percent /= (now - m_last_cpu);
|
||||
percent /= utils::get_thread_count();
|
||||
percent *= 100;
|
||||
}
|
||||
m_last_cpu = now;
|
||||
m_sys_cpu = timeSample.tms_stime;
|
||||
m_usr_cpu = timeSample.tms_utime;
|
||||
|
||||
return percent;
|
||||
#endif
|
||||
}
|
||||
|
||||
u32 cpu_stats::get_thread_count() // static
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// first determine the id of the current process
|
||||
DWORD const id = GetCurrentProcessId();
|
||||
|
||||
// then get a process list snapshot.
|
||||
HANDLE const snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
|
||||
// initialize the process entry structure.
|
||||
PROCESSENTRY32 entry = {0};
|
||||
entry.dwSize = sizeof(entry);
|
||||
|
||||
// get the first process info.
|
||||
BOOL ret = true;
|
||||
ret = Process32First(snapshot, &entry);
|
||||
while (ret && entry.th32ProcessID != id)
|
||||
{
|
||||
ret = Process32Next(snapshot, &entry);
|
||||
}
|
||||
CloseHandle(snapshot);
|
||||
return ret ? entry.cntThreads : 0;
|
||||
#elif defined(__APPLE__)
|
||||
const task_t task = mach_task_self();
|
||||
mach_msg_type_number_t thread_count;
|
||||
thread_act_array_t thread_list;
|
||||
if (task_threads(task, &thread_list, &thread_count) != KERN_SUCCESS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
vm_deallocate(task, reinterpret_cast<vm_address_t>(thread_list),
|
||||
sizeof(thread_t) * thread_count);
|
||||
return static_cast<u32>(thread_count);
|
||||
#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
|
||||
int mib[] = {
|
||||
CTL_KERN,
|
||||
KERN_PROC,
|
||||
KERN_PROC_PID,
|
||||
getpid(),
|
||||
#if defined(__NetBSD__)
|
||||
sizeof(struct kinfo_proc),
|
||||
1,
|
||||
#endif
|
||||
};
|
||||
u_int miblen = std::size(mib);
|
||||
struct kinfo_proc info;
|
||||
usz size = sizeof(info);
|
||||
if (sysctl(mib, miblen, &info, &size, NULL, 0))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return KP_NLWP(info);
|
||||
#elif defined(__OpenBSD__)
|
||||
int mib[] = {
|
||||
CTL_KERN,
|
||||
KERN_PROC,
|
||||
KERN_PROC_PID | KERN_PROC_SHOW_THREADS,
|
||||
getpid(),
|
||||
sizeof(struct kinfo_proc),
|
||||
0,
|
||||
};
|
||||
u_int miblen = std::size(mib);
|
||||
|
||||
// get number of structs
|
||||
usz size;
|
||||
if (sysctl(mib, miblen, NULL, &size, NULL, 0))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
mib[5] = size / mib[4];
|
||||
|
||||
// populate array of structs
|
||||
struct kinfo_proc info[mib[5]];
|
||||
if (sysctl(mib, miblen, &info, &size, NULL, 0))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// exclude empty members
|
||||
u32 thread_count{0};
|
||||
for (int i = 0; i < size / mib[4]; i++)
|
||||
{
|
||||
if (info[i].p_tid != -1)
|
||||
++thread_count;
|
||||
}
|
||||
return thread_count;
|
||||
#elif defined(__linux__)
|
||||
u32 thread_count{0};
|
||||
|
||||
DIR* proc_dir = opendir("/proc/self/task");
|
||||
if (proc_dir)
|
||||
{
|
||||
// proc available, iterate through tasks and count them
|
||||
struct dirent* entry;
|
||||
while ((entry = readdir(proc_dir)) != NULL)
|
||||
{
|
||||
if (entry->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
++thread_count;
|
||||
}
|
||||
|
||||
closedir(proc_dir);
|
||||
}
|
||||
return thread_count;
|
||||
#else
|
||||
// unimplemented
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
18
rpcs3/util/cpu_stats.hpp
Normal file
18
rpcs3/util/cpu_stats.hpp
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include "util/types.hpp"
|
||||
|
||||
namespace utils
|
||||
{
|
||||
class cpu_stats
|
||||
{
|
||||
u64 m_last_cpu, m_sys_cpu, m_usr_cpu;
|
||||
|
||||
public:
|
||||
cpu_stats();
|
||||
|
||||
double get_usage();
|
||||
|
||||
static u32 get_thread_count();
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue