Skip to content

Commit

Permalink
Merge pull request #7507 from thallium/master
Browse files Browse the repository at this point in the history
Use ULARGE_INTEGER to get time value from FILETIME on Windows
  • Loading branch information
babsingh authored Nov 1, 2024
2 parents be7ad36 + c23c257 commit 59c0eac
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 24 deletions.
45 changes: 38 additions & 7 deletions port/win32/omrsysinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -1226,14 +1226,23 @@ omrsysinfo_get_load_average(struct OMRPortLibrary *portLibrary, struct J9PortSys
intptr_t
omrsysinfo_get_CPU_utilization(struct OMRPortLibrary *portLibrary, struct J9SysinfoCPUTime *cpuTime)
{

FILETIME lpIdleTime;
ULARGE_INTEGER lpIdleTimeU64;
FILETIME lpKernelTime;
ULARGE_INTEGER lpKernelTimeU64;
FILETIME lpUserTime;
ULARGE_INTEGER lpUserTimeU64;
uint64_t idleTime = 0;
uint64_t kernelActiveTime = 0;
uint64_t userTime = 0;

memset(&lpIdleTime, 0, sizeof(lpIdleTime));
memset(&lpIdleTimeU64, 0, sizeof(lpIdleTimeU64));
memset(&lpKernelTime, 0, sizeof(lpKernelTime));
memset(&lpKernelTimeU64, 0, sizeof(lpKernelTimeU64));
memset(&lpUserTime, 0, sizeof(lpUserTime));
memset(&lpUserTimeU64, 0, sizeof(lpUserTimeU64));

/*
* GetSystemTimes returns the sum of CPU times across all CPUs
*/
Expand All @@ -1242,11 +1251,20 @@ omrsysinfo_get_CPU_utilization(struct OMRPortLibrary *portLibrary, struct J9Sysi
Trc_PRT_sysinfo_get_CPU_utilization_GetSystemTimesFailed(GetLastError());
return OMRPORT_ERROR_SYSINFO_GET_STATS_FAILED;
}
idleTime = (lpIdleTime.dwLowDateTime + (((uint64_t) lpIdleTime.dwHighDateTime) << 32)) * 100; /* FILETIME resolution is 100 ns */
kernelActiveTime = (lpKernelTime.dwLowDateTime + (((uint64_t) lpKernelTime.dwHighDateTime) << 32)) * 100
- idleTime; /* kernel time includes idle time */

lpIdleTimeU64.LowPart = lpIdleTime.dwLowDateTime;
lpIdleTimeU64.HighPart = lpIdleTime.dwHighDateTime;

lpKernelTimeU64.LowPart = lpKernelTime.dwLowDateTime;
lpKernelTimeU64.HighPart = lpKernelTime.dwHighDateTime;

lpUserTimeU64.LowPart = lpUserTime.dwLowDateTime;
lpUserTimeU64.HighPart = lpUserTime.dwHighDateTime;

idleTime = lpIdleTimeU64.QuadPart * 100; /* FILETIME resolution is 100 ns */
kernelActiveTime = (lpKernelTimeU64.QuadPart * 100) - idleTime; /* kernel time includes idle time */
Trc_PRT_sysinfo_get_CPU_utilization_GST_result("kernel active", kernelActiveTime);
userTime = (lpUserTime.dwLowDateTime + (((uint64_t) lpUserTime.dwHighDateTime) << 32)) * 100;
userTime = lpUserTimeU64.QuadPart * 100;
Trc_PRT_sysinfo_get_CPU_utilization_GST_result("user", userTime);
cpuTime->cpuTime = kernelActiveTime + userTime;
cpuTime->timestamp = portLibrary->time_nano_time(portLibrary);
Expand Down Expand Up @@ -2002,8 +2020,19 @@ omrsysinfo_get_process_start_time(struct OMRPortLibrary *portLibrary, uintptr_t
Trc_PRT_sysinfo_get_process_start_time_enter(pid);
if (0 != omrsysinfo_process_exists(portLibrary, pid)) {
double seconds = 0;
FILETIME createTime, exitTime, kernelTime, userTime;
FILETIME createTime;
ULARGE_INTEGER createTimeU64;
FILETIME exitTime;
FILETIME kernelTime;
FILETIME userTime;
HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)pid);

memset(&createTime, 0, sizeof(createTime));
memset(&createTimeU64, 0, sizeof(createTimeU64));
memset(&exitTime, 0, sizeof(exitTime));
memset(&kernelTime, 0, sizeof(kernelTime));
memset(&userTime, 0, sizeof(userTime));

if (NULL == process) {
rc = OMRPORT_ERROR_SYSINFO_NONEXISTING_PROCESS;
goto done;
Expand All @@ -2012,7 +2041,9 @@ omrsysinfo_get_process_start_time(struct OMRPortLibrary *portLibrary, uintptr_t
rc = OMRPORT_ERROR_SYSINFO_ERROR_GETTING_PROCESS_START_TIME;
goto cleanup;
}
seconds = (double)(*(LONGLONG *)&(createTime)) / OMRPORT_SYSINFO_WINDOWS_TICK;
createTimeU64.LowPart = createTime.dwLowDateTime;
createTimeU64.HighPart = createTime.dwHighDateTime;
seconds = ((double)createTimeU64.QuadPart) / OMRPORT_SYSINFO_WINDOWS_TICK;
computedProcessStartTimeInNanoseconds = (uint64_t)((seconds - OMRPORT_SYSINFO_SEC_TO_UNIX_EPOCH) * OMRPORT_SYSINFO_NS100_PER_SEC);
computedProcessStartTimeInNanoseconds *= 100;
cleanup:
Expand Down
108 changes: 91 additions & 17 deletions thread/common/thrprof.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,33 @@ omrthread_get_cpu_time_ex(omrthread_t thread, int64_t *cpuTime)
#if defined(OMR_OS_WINDOWS) && !defined(BREW)
{
intptr_t ret = 0;
FILETIME creationTime, exitTime, kernelTime, userTime;
int64_t totalTime;
FILETIME creationTime;
FILETIME exitTime;
FILETIME kernelTime;
FILETIME userTime;
int64_t totalTime = 0;

memset(&creationTime, 0, sizeof(creationTime));
memset(&exitTime, 0, sizeof(exitTime));
memset(&kernelTime, 0, sizeof(kernelTime));
memset(&userTime, 0, sizeof(userTime));

/* WARNING! Not supported on Win95! Need to test to ensure this fails gracefully */

if (GetThreadTimes(thread->handle, &creationTime, &exitTime, &kernelTime, &userTime)) {
totalTime = ((int64_t)kernelTime.dwLowDateTime | ((int64_t)kernelTime.dwHighDateTime << 32))
+ ((int64_t)userTime.dwLowDateTime | ((int64_t)userTime.dwHighDateTime << 32));
ULARGE_INTEGER kernelTimeU64;
ULARGE_INTEGER userTimeU64;

memset(&kernelTimeU64, 0, sizeof(kernelTimeU64));
memset(&userTimeU64, 0, sizeof(userTimeU64));

kernelTimeU64.LowPart = kernelTime.dwLowDateTime;
kernelTimeU64.HighPart = kernelTime.dwHighDateTime;

userTimeU64.LowPart = userTime.dwLowDateTime;
userTimeU64.HighPart = userTime.dwHighDateTime;

totalTime = (int64_t)(kernelTimeU64.QuadPart + userTimeU64.QuadPart);

/* totalTime is in 100's of nanos. Convert to nanos */
*cpuTime = totalTime * 100;
Expand Down Expand Up @@ -409,13 +428,27 @@ omrthread_get_user_time(omrthread_t thread)
*
*/

FILETIME creationTime, exitTime, kernelTime, userTime;
int64_t totalTime;
FILETIME creationTime;
FILETIME exitTime;
FILETIME kernelTime;
FILETIME userTime;
int64_t totalTime = 0;

memset(&creationTime, 0, sizeof(creationTime));
memset(&exitTime, 0, sizeof(exitTime));
memset(&kernelTime, 0, sizeof(kernelTime));
memset(&userTime, 0, sizeof(userTime));

/* WARNING! Not supported on Win95! Need to test to ensure this fails gracefully */

if (GetThreadTimes(thread->handle, &creationTime, &exitTime, &kernelTime, &userTime)) {
totalTime = ((int64_t)userTime.dwLowDateTime | ((int64_t)userTime.dwHighDateTime << 32));
ULARGE_INTEGER userTimeU64;

memset(&userTimeU64, 0, sizeof(userTimeU64));

userTimeU64.LowPart = userTime.dwLowDateTime;
userTimeU64.HighPart = userTime.dwHighDateTime;
totalTime = (int64_t)userTimeU64.QuadPart;

/* totalTime is in 100's of nanos. Convert to nanos */
return totalTime * 100;
Expand Down Expand Up @@ -673,12 +706,31 @@ int64_t
omrthread_get_process_cpu_time(void)
{
#if defined(OMR_OS_WINDOWS) && !defined(BREW)
FILETIME creationTime, exitTime, kernelTime, userTime;
int64_t totalTime;
FILETIME creationTime;
FILETIME exitTime;
FILETIME kernelTime;
FILETIME userTime;
int64_t totalTime = 0;

memset(&creationTime, 0, sizeof(creationTime));
memset(&exitTime, 0, sizeof(exitTime));
memset(&kernelTime, 0, sizeof(kernelTime));
memset(&userTime, 0, sizeof(userTime));

if (GetProcessTimes(GetCurrentProcess(), &creationTime, &exitTime, &kernelTime, &userTime)) {
totalTime = ((int64_t)kernelTime.dwLowDateTime | ((int64_t)kernelTime.dwHighDateTime << 32))
+ ((int64_t)userTime.dwLowDateTime | ((int64_t)userTime.dwHighDateTime << 32));
ULARGE_INTEGER kernelTimeU64;
ULARGE_INTEGER userTimeU64;

memset(&kernelTimeU64, 0, sizeof(kernelTimeU64));
memset(&userTimeU64, 0, sizeof(userTimeU64));

kernelTimeU64.LowPart = kernelTime.dwLowDateTime;
kernelTimeU64.HighPart = kernelTime.dwHighDateTime;

userTimeU64.LowPart = userTime.dwLowDateTime;
userTimeU64.HighPart = userTime.dwHighDateTime;

totalTime = (int64_t)(kernelTimeU64.QuadPart + userTimeU64.QuadPart);

/* totalTime is in 100's of nanos. Convert to nanos */
return totalTime * GET_PROCESS_TIMES_IN_NANO;
Expand Down Expand Up @@ -715,10 +767,20 @@ omrthread_get_process_times(omrthread_process_time_t *processTime)
* WARNING: GetProcessTimes does not exist on pre-Win 98
*/
if (GetProcessTimes(GetCurrentProcess(), &creationTime, &exitTime, &systemTime, &userTime)) {
processTime->_userTime = GET_PROCESS_TIMES_IN_NANO *
((int64_t)userTime.dwLowDateTime | ((int64_t)userTime.dwHighDateTime << 32));
processTime->_systemTime = GET_PROCESS_TIMES_IN_NANO *
((int64_t)systemTime.dwLowDateTime | ((int64_t)systemTime.dwHighDateTime << 32));
ULARGE_INTEGER systemTimeU64;
ULARGE_INTEGER userTimeU64;

memset(&systemTimeU64, 0, sizeof(systemTimeU64));
memset(&userTimeU64, 0, sizeof(userTimeU64));

systemTimeU64.LowPart = systemTime.dwLowDateTime;
systemTimeU64.HighPart = systemTime.dwHighDateTime;

userTimeU64.LowPart = userTime.dwLowDateTime;
userTimeU64.HighPart = userTime.dwHighDateTime;

processTime->_userTime = (int64_t)(GET_PROCESS_TIMES_IN_NANO * userTimeU64.QuadPart);
processTime->_systemTime = (int64_t)(GET_PROCESS_TIMES_IN_NANO * systemTimeU64.QuadPart);
return 0;
} else {
/* GetLastError() indicates reason for failure in GetProcessTimes(). */
Expand Down Expand Up @@ -1060,9 +1122,21 @@ omrthread_get_thread_times(omrthread_thread_time_t *threadTime)
memset(&userTime, 0, sizeof(userTime));

if (GetThreadTimes(self->handle, &creationTime, &exitTime, &kernelTime, &userTime)) {
ULARGE_INTEGER kernelTimeU64;
ULARGE_INTEGER userTimeU64;

memset(&kernelTimeU64, 0, sizeof(kernelTimeU64));
memset(&userTimeU64, 0, sizeof(userTimeU64));

kernelTimeU64.LowPart = kernelTime.dwLowDateTime;
kernelTimeU64.HighPart = kernelTime.dwHighDateTime;

userTimeU64.LowPart = userTime.dwLowDateTime;
userTimeU64.HighPart = userTime.dwHighDateTime;

/* Time is in 100's of nanos. Convert to nanos. */
threadTime->sysTime = ((int64_t)kernelTime.dwLowDateTime | ((int64_t)kernelTime.dwHighDateTime << 32)) * 100;
threadTime->userTime = ((int64_t)userTime.dwLowDateTime | ((int64_t)userTime.dwHighDateTime << 32)) * 100;
threadTime->sysTime = (int64_t)(kernelTimeU64.QuadPart * 100);
threadTime->userTime = (int64_t)(userTimeU64.QuadPart * 100);

return 0;
}
Expand Down

0 comments on commit 59c0eac

Please sign in to comment.