зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1742472 - Use QueryProcessCycleTime on Windows to report total CPU time spent when the CPU has a constant TSC, r=gerald,jrmuizel.
Differential Revision: https://phabricator.services.mozilla.com/D131834
This commit is contained in:
Родитель
a2e85fcc9f
Коммит
5373598e93
|
@ -179,6 +179,8 @@ bool avx2_enabled = has_avx() && has_cpuid_bits(7u, ebx, (1u << 5));
|
|||
bool aes_enabled = has_cpuid_bits(1u, ecx, (1u << 25));
|
||||
# endif
|
||||
|
||||
bool has_constant_tsc = has_cpuid_bits(0x80000007u, edx, (1u << 8));
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace sse_private
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
* mozilla::supports_avx
|
||||
* mozilla::supports_avx2
|
||||
* mozilla::supports_aes
|
||||
* mozilla::has_constant_tsc
|
||||
*
|
||||
* If you're writing code using inline assembly, you should guard it with a
|
||||
* call to one of these functions. For instance:
|
||||
|
@ -223,6 +224,7 @@ extern bool MFBT_DATA avx2_enabled;
|
|||
# if !defined(MOZILLA_PRESUME_AES)
|
||||
extern bool MFBT_DATA aes_enabled;
|
||||
# endif
|
||||
extern bool MFBT_DATA has_constant_tsc;
|
||||
|
||||
#endif
|
||||
} // namespace sse_private
|
||||
|
@ -345,6 +347,12 @@ inline bool supports_aes() { return sse_private::aes_enabled; }
|
|||
inline bool supports_aes() { return false; }
|
||||
#endif
|
||||
|
||||
#ifdef MOZILLA_SSE_HAVE_CPUID_DETECTION
|
||||
inline bool has_constant_tsc() { return sse_private::has_constant_tsc; }
|
||||
#else
|
||||
inline bool has_constant_tsc() { return false; }
|
||||
#endif
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* !defined(mozilla_SSE_h_) */
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "mozilla/ProcInfo.h"
|
||||
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
||||
#include "mozilla/SSE.h"
|
||||
#include "nsMemoryReporterManager.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
|
@ -18,14 +19,61 @@ typedef HRESULT(WINAPI* GETTHREADDESCRIPTION)(HANDLE hThread,
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
uint64_t ToNanoSeconds(const FILETIME& aFileTime) {
|
||||
static uint64_t ToNanoSeconds(const FILETIME& aFileTime) {
|
||||
// FILETIME values are 100-nanoseconds units, converting
|
||||
ULARGE_INTEGER usec = {{aFileTime.dwLowDateTime, aFileTime.dwHighDateTime}};
|
||||
return usec.QuadPart * 100;
|
||||
}
|
||||
|
||||
/* Get the CPU frequency to use to convert cycle time values to actual time.
|
||||
* @returns the TSC frequency in MHz, or 0 if converting cycle time values
|
||||
* should not be attempted. */
|
||||
static int GetCycleTimeFrequency() {
|
||||
static int result = -1;
|
||||
if (result != -1) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = 0;
|
||||
|
||||
// Having a constant TSC is required to convert cycle time to actual time.
|
||||
if (!mozilla::has_constant_tsc()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Now get the nominal CPU frequency.
|
||||
HKEY key;
|
||||
static const WCHAR keyName[] =
|
||||
L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
|
||||
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, KEY_QUERY_VALUE, &key) ==
|
||||
ERROR_SUCCESS) {
|
||||
DWORD data, len;
|
||||
len = sizeof(data);
|
||||
|
||||
if (RegQueryValueEx(key, L"~Mhz", 0, 0, reinterpret_cast<LPBYTE>(&data),
|
||||
&len) == ERROR_SUCCESS) {
|
||||
result = static_cast<int>(data);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult GetCpuTimeSinceProcessStartInMs(uint64_t* aResult) {
|
||||
FILETIME createTime, exitTime, kernelTime, userTime;
|
||||
int frequencyInMHz = GetCycleTimeFrequency();
|
||||
if (frequencyInMHz) {
|
||||
uint64_t cpuCycleCount;
|
||||
if (!QueryProcessCycleTime(::GetCurrentProcess(), &cpuCycleCount)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
constexpr int HZ_PER_MHZ = 1000000;
|
||||
*aResult =
|
||||
cpuCycleCount / (frequencyInMHz * (HZ_PER_MHZ / PR_MSEC_PER_SEC));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!GetProcessTimes(::GetCurrentProcess(), &createTime, &exitTime,
|
||||
&kernelTime, &userTime)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
|
Загрузка…
Ссылка в новой задаче