mirror of https://github.com/PCSX2/pcsx2.git
Threading/Win32: Use QueryThreadCycleTime() for thread CPU time
This commit is contained in:
parent
7d81c979fe
commit
5eae7a6328
|
@ -21,6 +21,7 @@
|
|||
|
||||
#if defined(_WIN32)
|
||||
#include "RedtapeWindows.h"
|
||||
#include "Threading.h"
|
||||
#elif defined(__APPLE__)
|
||||
#include <mach/mach_init.h>
|
||||
#include <mach/thread_act.h>
|
||||
|
@ -212,13 +213,9 @@ namespace Common
|
|||
ThreadCPUTimer::Value ThreadCPUTimer::GetCurrentValue() const
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
FILETIME create, exit, user, kernel;
|
||||
if (!m_thread_handle || !GetThreadTimes((HANDLE)m_thread_handle, &create, &exit, &user, &kernel))
|
||||
return 0;
|
||||
|
||||
Value value = (static_cast<Value>(user.dwHighDateTime) << 32) | (static_cast<Value>(user.dwLowDateTime));
|
||||
value += (static_cast<Value>(kernel.dwHighDateTime) << 32) | (static_cast<Value>(kernel.dwLowDateTime));
|
||||
return value;
|
||||
ULONG64 ret = 0;
|
||||
QueryThreadCycleTime((HANDLE)m_thread_handle, &ret);
|
||||
return ret;
|
||||
#elif defined(__APPLE__)
|
||||
thread_basic_info_data_t info;
|
||||
mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
|
||||
|
@ -291,7 +288,16 @@ namespace Common
|
|||
double ThreadCPUTimer::GetUtilizationPercentage(Timer::Value time_diff, Value cpu_time_diff)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return ((static_cast<double>(cpu_time_diff) * 10000.0) / (static_cast<double>(time_diff) / s_counter_frequency));
|
||||
// we need to convert from the rdtsc domain to the QPC domain (may not necessarily match)
|
||||
static bool ratio_initialized = false;
|
||||
static double ratio = 0.0;
|
||||
if (unlikely(!ratio_initialized))
|
||||
{
|
||||
ratio = (static_cast<double>(Threading::GetThreadTicksPerSecond()) / static_cast<double>(GetTickFrequency())) / 100.0;
|
||||
ratio_initialized = true;
|
||||
}
|
||||
|
||||
return (static_cast<double>(cpu_time_diff) / (static_cast<double>(time_diff) * ratio));
|
||||
#elif defined(__APPLE__)
|
||||
// microseconds, but time_tiff is in nanoseconds, so multiply by 1000 * 100
|
||||
return (static_cast<double>(cpu_time_diff) * 100000.0) / static_cast<double>(time_diff);
|
||||
|
@ -304,8 +310,7 @@ namespace Common
|
|||
double ThreadCPUTimer::ConvertValueToSeconds(Value value)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
// 100ns units
|
||||
return (static_cast<double>(value) / 10000000.0);
|
||||
return (static_cast<double>(value) / Threading::GetThreadTicksPerSecond());
|
||||
#elif defined(__APPLE__)
|
||||
// microseconds
|
||||
return (static_cast<double>(value) / 1000000.0);
|
||||
|
@ -318,7 +323,7 @@ namespace Common
|
|||
double ThreadCPUTimer::ConvertValueToMilliseconds(Value value)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return (static_cast<double>(value) / 10000.0);
|
||||
return (static_cast<double>(value) / (Threading::GetThreadTicksPerSecond() / 1000.0));
|
||||
#elif defined(__APPLE__)
|
||||
return (static_cast<double>(value) / 1000.0);
|
||||
#else
|
||||
|
@ -329,7 +334,7 @@ namespace Common
|
|||
double ThreadCPUTimer::ConvertValueToNanoseconds(Value value)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
return (static_cast<double>(value) * 100.0);
|
||||
return (static_cast<double>(value) / (Threading::GetThreadTicksPerSecond() / 1000000000.0));
|
||||
#elif defined(__APPLE__)
|
||||
return (static_cast<double>(value) * 1000.0);
|
||||
#else
|
||||
|
|
|
@ -47,39 +47,29 @@ __fi void Threading::DisableHiresScheduler()
|
|||
timeEndPeriod(1);
|
||||
}
|
||||
|
||||
// This hacky union would probably fail on some cpu platforms if the contents of FILETIME aren't
|
||||
// packed (but for any x86 CPU and microsoft compiler, they will be).
|
||||
union FileTimeSucks
|
||||
{
|
||||
FILETIME filetime;
|
||||
u64 u64time;
|
||||
};
|
||||
|
||||
u64 Threading::GetThreadCpuTime()
|
||||
{
|
||||
FileTimeSucks user, kernel;
|
||||
FILETIME dummy;
|
||||
GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernel.filetime, &user.filetime);
|
||||
return user.u64time + kernel.u64time;
|
||||
u64 ret = 0;
|
||||
QueryThreadCycleTime(GetCurrentThread(), &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
u64 Threading::GetThreadTicksPerSecond()
|
||||
{
|
||||
return 10000000;
|
||||
// On x86, despite what the MS documentation says, this basically appears to be rdtsc.
|
||||
// So, the frequency is our base clock speed (and stable regardless of power management).
|
||||
static u64 frequency = 0;
|
||||
if (unlikely(frequency == 0))
|
||||
frequency = x86caps.CachedMHz() * u64(1000000);
|
||||
return frequency;
|
||||
}
|
||||
|
||||
u64 Threading::pxThread::GetCpuTime() const
|
||||
{
|
||||
if (!m_native_handle)
|
||||
return 0;
|
||||
|
||||
FileTimeSucks user, kernel;
|
||||
FILETIME dummy;
|
||||
|
||||
if (GetThreadTimes((HANDLE)m_native_handle, &dummy, &dummy, &kernel.filetime, &user.filetime))
|
||||
return user.u64time + kernel.u64time;
|
||||
|
||||
return 0; // thread prolly doesn't exist anymore.
|
||||
u64 ret = 0;
|
||||
if (m_native_handle)
|
||||
QueryThreadCycleTime((HANDLE)m_native_handle, &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Threading::pxThread::_platform_specific_OnStartInThread()
|
||||
|
|
Loading…
Reference in New Issue