Skip to content

Commit

Permalink
Get the process start time
Browse files Browse the repository at this point in the history
Get the process start time on linux, windows, osx, aix and
z/os.

Issue: #7201
Signed-off-by: Amarpreet Singh <[email protected]>
  • Loading branch information
singh264 committed Jan 8, 2024
1 parent e2e3a00 commit 403d584
Show file tree
Hide file tree
Showing 12 changed files with 432 additions and 148 deletions.
77 changes: 77 additions & 0 deletions fvtest/porttest/si.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@
#endif /* defined(J9ZOS390) */
#include <sys/resource.h> /* For RLIM_INFINITY */
#endif /* !defined(OMR_OS_WINDOWS) */
#if defined(OMR_OS_WINDOWS)
#include <windows.h>
#else /* defined(OMR_OS_WINDOWS) */
#include <sys/wait.h>
#include <unistd.h>
#endif /* defined(OMR_OS_WINDOWS) */

#if defined(J9ZOS390) && !defined(OMR_EBCDIC)
#include "atoe.h"
Expand Down Expand Up @@ -3119,3 +3125,74 @@ TEST(PortSysinfoTest, GetProcessorDescription)
ASSERT_TRUE(feature == TRUE || feature == FALSE);
}
}

/**
* Test: GetProcessorStartTimeOfNonExistingProcessTest.
* Description: Verify that getting the process start time for a non-existing process (UINTPTR_MAX) results in 0 nanoseconds.
* Passing Condition: The expected process start time is 0 nanoseconds, and the actual process start time matches this value.
*/
TEST(PortSysinfoTest, GetProcessorStartTimeOfNonExistingProcessTest)
{
OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());
/*
* If a pid of UINTPTR_MAX exists in the future then the test will need to be modified.
* UINTPTR_MAX represents the maximum unsigned integer value, which can be a 32-bit or a 64-bit depending on the system.
* On unix systems, a pid is represented by pid_t, which can be a 32-bit or a 64-bit signed integer.
* On windows systems, a pid is represented by DWORD, which is a 32-bit unsigned integer, and
* the maximum value of DWORD is not a valid pid as it is reserved for use by the ASFW_ANY parameter.
*/
uintptr_t pid = UINTPTR_MAX;
uint64_t expectedProcessStartTimeInNanoseconds = 0;
uint64_t actualProcessStartTimeInNanoseconds = omrsysinfo_get_process_start_time(pid);
#if !defined(OMRZTPF)
/* The method omrsysinfo_get_process_start_time is not implemented on z/TPF. */
ASSERT_EQ(expectedProcessStartTimeInNanoseconds, actualProcessStartTimeInNanoseconds);
#endif /* !defined(OMRZTPF) */
}

/**
* Test: GetProcessorStartTimeOfExistingProcessTest.
* Description: Verify that getting the process start time for an existing process results in a valid timestamp.
* Passing Condition: The process start time is greater than the test start time and less than the current time at the end of the test.
*/
TEST(PortSysinfoTest, GetProcessorStartTimeOfExistingProcessTest)
{
OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary());
uintptr_t pid = UINTPTR_MAX;
uintptr_t success = 0;
uint64_t testStartTimeInNanoseconds = omrtime_current_time_nanos(&success);
uint64_t processStartTimeInNanoseconds = 0;
#if defined(LINUX) || defined(OSX) || defined(AIXPPC) || defined(J9ZOS390)
int status = 0;
sleep(3);
pid = fork();
ASSERT_NE(pid, -1);
/* The if block will only be invoked by the child process. */
if (0 == pid) {
sleep(10);
/* A call to exit allows the child process to stop and avoids a timeout on x86-64 macOS. */
exit(0);
}
processStartTimeInNanoseconds = omrsysinfo_get_process_start_time(pid);
waitpid(pid, &status, 0);
#elif defined(OMR_OS_WINDOWS) /* defined(LINUX) || defined(OSX) || defined(AIXPPC) || defined(J9ZOS390) */
STARTUPINFO si;
PROCESS_INFORMATION pi;
BOOL ret = FALSE;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
ret = CreateProcess(NULL, "cmd.exe /c timeout /t 10", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
ASSERT_EQ(ret, TRUE);
pid = (uintptr_t)GetProcessId(pi.hProcess);
processStartTimeInNanoseconds = omrsysinfo_get_process_start_time(pid);
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
#endif /* defined(LINUX) || defined(OSX) || defined(AIXPPC) || defined(J9ZOS390) */
#if !defined(OMRZTPF)
/* The method omrsysinfo_get_process_start_time is not implemented on z/TPF. */
ASSERT_GT(processStartTimeInNanoseconds, testStartTimeInNanoseconds);
ASSERT_LT(processStartTimeInNanoseconds, omrtime_current_time_nanos(&success));
#endif /* !defined(OMRZTPF) */
}
3 changes: 3 additions & 0 deletions include_core/omrport.h
Original file line number Diff line number Diff line change
Expand Up @@ -2459,6 +2459,8 @@ typedef struct OMRPortLibrary {
int32_t (*sysinfo_cgroup_subsystem_iterator_next)(struct OMRPortLibrary *portLibrary, struct OMRCgroupMetricIteratorState *state, struct OMRCgroupMetricElement *metricElement);
/** see @ref omrsysinfo.c::omrsysinfo_cgroup_subsystem_iterator_destroy "omrsysinfo_cgroup_subsystem_iterator_destroy"*/
void (*sysinfo_cgroup_subsystem_iterator_destroy)(struct OMRPortLibrary *portLibrary, struct OMRCgroupMetricIteratorState *state);
/** see @ref omrsysinfo.c::omrsysinfo_get_process_start_time "omrsysinfo_get_process_start_time"*/
uint64_t (*sysinfo_get_process_start_time)(struct OMRPortLibrary *portLibrary, uintptr_t pid);
/** see @ref omrport.c::omrport_init_library "omrport_init_library"*/
int32_t (*port_init_library)(struct OMRPortLibrary *portLibrary, uintptr_t size) ;
/** see @ref omrport.c::omrport_startup_library "omrport_startup_library"*/
Expand Down Expand Up @@ -3102,6 +3104,7 @@ extern J9_CFUNC int32_t omrport_getVersion(struct OMRPortLibrary *portLibrary);
#define omrsysinfo_cgroup_subsystem_iterator_metricKey(param1, param2) privateOmrPortLibrary->sysinfo_cgroup_subsystem_iterator_metricKey(privateOmrPortLibrary, param1, param2)
#define omrsysinfo_cgroup_subsystem_iterator_next(param1, param2) privateOmrPortLibrary->sysinfo_cgroup_subsystem_iterator_next(privateOmrPortLibrary, param1, param2)
#define omrsysinfo_cgroup_subsystem_iterator_destroy(param1) privateOmrPortLibrary->sysinfo_cgroup_subsystem_iterator_destroy(privateOmrPortLibrary, param1)
#define omrsysinfo_get_process_start_time(param1) privateOmrPortLibrary->sysinfo_get_process_start_time(privateOmrPortLibrary, param1)
#define omrintrospect_startup() privateOmrPortLibrary->introspect_startup(privateOmrPortLibrary)
#define omrintrospect_shutdown() privateOmrPortLibrary->introspect_shutdown(privateOmrPortLibrary)
#define omrintrospect_set_suspend_signal_offset(param1) privateOmrPortLibrary->introspect_set_suspend_signal_offset(privateOmrPortLibrary, param1)
Expand Down
3 changes: 3 additions & 0 deletions nls/portnls.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,5 +176,8 @@
#define J9NLS_PORT_RUNNING_IN_CONTAINER_FAILURE__MODULE 0x504f5254
#define J9NLS_PORT_RUNNING_IN_CONTAINER_FAILURE__ID 50
#define J9NLS_PORT_RUNNING_IN_CONTAINER_FAILURE J9NLS_PORT_RUNNING_IN_CONTAINER_FAILURE__MODULE, J9NLS_PORT_RUNNING_IN_CONTAINER_FAILURE__ID
#define J9NLS_PORT_SYSINFO_UNSUPPORTED_PLATFORM_ERROR__MODULE 0x504f5254
#define J9NLS_PORT_SYSINFO_UNSUPPORTED_PLATFORM_ERROR__ID 51
#define J9NLS_PORT_SYSINFO_UNSUPPORTED_PLATFORM_ERROR J9NLS_PORT_SYSINFO_UNSUPPORTED_PLATFORM_ERROR__MODULE, J9NLS_PORT_SYSINFO_UNSUPPORTED_PLATFORM_ERROR__ID

#endif
1 change: 1 addition & 0 deletions port/common/omrport.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ static OMRPortLibrary MainPortLibraryTable = {
omrsysinfo_cgroup_subsystem_iterator_metricKey, /* sysinfo_cgroup_subsystem_iterator_metricKey */
omrsysinfo_cgroup_subsystem_iterator_next, /* sysinfo_cgroup_subsystem_iterator_next */
omrsysinfo_cgroup_subsystem_iterator_destroy, /* sysinfo_cgroup_subsystem_iterator_destroy */
omrsysinfo_get_process_start_time, /* sysinfo_get_process_start_time */
omrport_init_library, /* port_init_library */
omrport_startup_library, /* port_startup_library */
omrport_create_library, /* port_create_library */
Expand Down
10 changes: 10 additions & 0 deletions port/common/omrport.tdf
Original file line number Diff line number Diff line change
Expand Up @@ -1630,3 +1630,13 @@ TraceEvent=Trc_PRT_sl_open_shared_library_noload Group=sl Overhead=1 Level=3 NoE
TraceException=Trc_PRT_retrieveLinuxMemoryStats_failedOpeningSwappinessFs Group=sysinfo Overhead=1 Level=1 NoEnv Template="retrieveLinuxMemoryStats: Failed to open /proc/sys/vm/swappiness. Error code = %d."
TraceException=Trc_PRT_retrieveLinuxMemoryStats_failedReadingSwappiness Group=sysinfo Overhead=1 Level=1 NoEnv Template="retrieveLinuxMemoryStats: Failed to read /proc/sys/vm/swappiness. Error code = %d."
TraceException=Trc_PRT_retrieveLinuxMemoryStats_unexpectedSwappinessFormat Group=sysinfo Overhead=1 Level=1 NoEnv Template="retrieveLinuxMemoryStats: Expected %d items to read, but read %d items."

TraceEntry=Trc_PRT_sysinfo_get_process_start_time_enter Group=sysinfo Overhead=1 Level=1 NoEnv Template="Enter omrsysinfo_get_process_start_time for pid %llu"
TraceEntry=Trc_PRT_sysinfo_get_process_start_time_stat_error Group=sysinfo Overhead=1 Level=1 NoEnv Template="omrsysinfo_get_process_start_time stat error for pid %llu"
TraceEntry=Trc_PRT_sysinfo_get_process_start_time_sysctl_error Group=sysinfo Overhead=1 Level=1 NoEnv Template="omrsysinfo_get_process_start_time sysctl error for pid %llu"
TraceEntry=Trc_PRT_sysinfo_get_process_start_time_pid_does_not_exist Group=sysinfo Overhead=1 Level=1 NoEnv Template="omrsysinfo_get_process_start_time pid %llu does not exist"
TraceEntry=Trc_PRT_sysinfo_get_process_start_time_getprocs_error Group=sysinfo Overhead=1 Level=1 NoEnv Template="omrsysinfo_get_process_start_time getprocs error for pid %llu"
TraceEntry=Trc_PRT_sysinfo_get_process_start_time_getthent_error Group=sysinfo Overhead=1 Level=1 NoEnv Template="omrsysinfo_get_process_start_time getthent error for pid %llu"
TraceEntry=Trc_PRT_sysinfo_get_process_start_time_OpenProcess_error Group=sysinfo Overhead=1 Level=1 NoEnv Template="omrsysinfo_get_process_start_time OpenProcess error for pid %llu"
TraceEntry=Trc_PRT_sysinfo_get_process_start_time_GetProcessTimes_error Group=sysinfo Overhead=1 Level=1 NoEnv Template="omrsysinfo_get_process_start_time GetProcessTimes error for pid %llu"
TraceExit=Trc_PRT_sysinfo_get_process_start_time_exit Group=sysinfo Overhead=1 Level=1 NoEnv Template="Exit omrsysinfo_get_process_start_time for pid %llu"
12 changes: 12 additions & 0 deletions port/common/omrsysinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -1178,3 +1178,15 @@ omrsysinfo_cgroup_subsystem_iterator_destroy(struct OMRPortLibrary *portLibrary,
{
return;
}

/**
* Get the process start time in ns precision epoch time.
* @param[in] portLibrary The port library
* @param[in] pid The process ID
* @return 0 if the process does not exist, process start time in ns precision epoch time if the process exists
*/
uint64_t
omrsysinfo_get_process_start_time(struct OMRPortLibrary *portLibrary, uintptr_t pid)
{
return 0;
}
2 changes: 2 additions & 0 deletions port/omrportpriv.h
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,8 @@ extern J9_CFUNC int32_t
omrsysinfo_cgroup_subsystem_iterator_next(struct OMRPortLibrary *portLibrary, struct OMRCgroupMetricIteratorState *state, struct OMRCgroupMetricElement *metricElement);
extern J9_CFUNC void
omrsysinfo_cgroup_subsystem_iterator_destroy(struct OMRPortLibrary *portLibrary, struct OMRCgroupMetricIteratorState *state);
extern J9_CFUNC uint64_t
omrsysinfo_get_process_start_time(struct OMRPortLibrary *portLibrary, uintptr_t pid);

/* J9SourceJ9Signal*/
extern J9_CFUNC int32_t
Expand Down
109 changes: 109 additions & 0 deletions port/unix/omrsysinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@


#if defined(J9ZOS390)
#include "omrgetthent.h"
#include "omrsimap.h"
#endif /* defined(J9ZOS390) */

Expand All @@ -95,6 +96,7 @@

#if defined(AIXPPC)
#include <fcntl.h>
#include <procinfo.h>
#include <sys/procfs.h>
#include <sys/systemcfg.h>
#endif /* defined(AIXPPC) */
Expand Down Expand Up @@ -195,6 +197,19 @@ uintptr_t Get_Number_Of_CPUs();
#define JIFFIES 100
#define USECS_PER_SEC 1000000
#define TICKS_TO_USEC ((uint64_t)(USECS_PER_SEC/JIFFIES))
#define OMRPORT_SYSINFO_PROC_DIR_BUFFER_SIZE 256
#define OMRPORT_SYSINFO_STAT_ERROR -1
#define OMRPORT_SYSINFO_NUM_SYSCTL_ARGS 4
#define OMRPORT_SYSINFO_SYSCTL_ERROR -1
#define OMRPORT_SYSINFO_NANOSECONDS_PER_MICROSECOND 1000ULL
#define OMRPORT_SYSINFO_GETPROCS_ERROR -1
#define OMRPORT_SYSINFO_GETPROCS_NONEXISTING_PID_ERROR 0
#define OMRPORT_SYSINFO_GETTHENT_ERROR -1
#if defined(_LP64)
#define GETTHENT BPX4GTH
#else /* defined(_LP64) */
#define GETTHENT BPX1GTH
#endif /* defined(_LP64) */

static uintptr_t copyEnvToBuffer(struct OMRPortLibrary *portLibrary, void *args);
static uintptr_t copyEnvToBufferSignalHandler(struct OMRPortLibrary *portLib, uint32_t gpType, void *gpInfo, void *unUsed);
Expand Down Expand Up @@ -598,6 +613,19 @@ static intptr_t searchSystemPath(struct OMRPortLibrary *portLibrary, char *filen
#if defined(J9ZOS390)
static void setOSFeature(struct OMROSDesc *desc, uint32_t feature);
static intptr_t getZOSDescription(struct OMRPortLibrary *portLibrary, struct OMROSDesc *desc);
#if defined(_LP64)
#pragma linkage(BPX4GTH,OS)
#else /* defined(_LP64) */
#pragma linkage(BPX1GTH,OS)
#endif /* defined(_LP64) */
void GETTHENT(
unsigned int *inputSize,
unsigned char **input,
unsigned int *outputSize,
unsigned char **output,
unsigned int *ret,
unsigned int *retCode,
unsigned int *reasonCode);
#endif /* defined(J9ZOS390) */

#if !defined(RS6000) && !defined(J9ZOS390) && !defined(OSX) && !defined(OMRZTPF)
Expand Down Expand Up @@ -7354,3 +7382,84 @@ get_Dispatch_IstreamCount(void) {
return (uintptr_t)numberOfIStreams;
}
#endif /* defined(OMRZTPF) */

uint64_t
omrsysinfo_get_process_start_time(struct OMRPortLibrary *portLibrary, uintptr_t pid)
{
Trc_PRT_sysinfo_get_process_start_time_enter((unsigned long long)pid);
uint64_t processStartTimeInNanoseconds = 0;
if (0 != omrsysinfo_process_exists(portLibrary, pid)) {
#if defined(LINUX)
char procDir[OMRPORT_SYSINFO_PROC_DIR_BUFFER_SIZE] = {0};
struct stat st;
snprintf(procDir, sizeof(procDir), "/proc/%" PRIuPTR, pid);
if (OMRPORT_SYSINFO_STAT_ERROR == stat(procDir, &st)) {
Trc_PRT_sysinfo_get_process_start_time_stat_error((unsigned long long)pid);
goto done;
}
processStartTimeInNanoseconds = (uint64_t)st.st_mtime * OMRPORT_TIME_DELTA_IN_NANOSECONDS + st.st_mtim.tv_nsec;
#elif defined(OSX) /* defined(LINUX) */
int mib[OMRPORT_SYSINFO_NUM_SYSCTL_ARGS] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
size_t len = sizeof(struct kinfo_proc);
struct kinfo_proc procInfo;
if (OMRPORT_SYSINFO_SYSCTL_ERROR == sysctl(mib, OMRPORT_SYSINFO_NUM_SYSCTL_ARGS, &procInfo, &len, NULL, 0)) {
Trc_PRT_sysinfo_get_process_start_time_sysctl_error((unsigned long long)pid);
goto done;
}
if (0 == len) {
Trc_PRT_sysinfo_get_process_start_time_pid_does_not_exist((unsigned long long)pid);
goto done;
}
processStartTimeInNanoseconds =
((uint64_t)procInfo.kp_proc.p_starttime.tv_sec * OMRPORT_TIME_DELTA_IN_NANOSECONDS) +
((uint64_t)procInfo.kp_proc.p_starttime.tv_usec * OMRPORT_SYSINFO_NANOSECONDS_PER_MICROSECOND);
#elif defined(AIXPPC) /* defined(OSX) */
pid_t convertedPid = (pid_t)pid;
struct procsinfo procInfos[] = {0};
int ret = getprocs(procInfos, sizeof(procInfos[0]), NULL, 0, &convertedPid, sizeof(procInfos) / sizeof(procInfos[0]));
if (OMRPORT_SYSINFO_GETPROCS_ERROR == ret) {
Trc_PRT_sysinfo_get_process_start_time_getprocs_error((unsigned long long)pid);
goto done;
} else if (OMRPORT_SYSINFO_GETPROCS_NONEXISTING_PID_ERROR == ret) {
Trc_PRT_sysinfo_get_process_start_time_pid_does_not_exist((unsigned long long)pid);
goto done;
}
processStartTimeInNanoseconds = (uint64_t)(procInfos[0].pi_start) * OMRPORT_TIME_DELTA_IN_NANOSECONDS;
#elif defined(J9ZOS390) /* defined(AIXPPC) */
pgtha pgtha;
ProcessData processData;
pgthc *currentProcessInfo = NULL;
uint32_t dataOffset = 0;
uint32_t inputSize = sizeof(pgtha);
unsigned char *input = (unsigned char *)&pgtha;
uint32_t outputSize = sizeof(ProcessData);
unsigned char *output = (unsigned char *)&processData;
uint32_t ret = 0;
uint32_t retCode = 0;
uint32_t reasonCode = 0;
memset(input, 0, sizeof(pgtha));
memset(output, 0, sizeof(processData));
pgtha.pid = pid;
pgtha.accesspid = PGTHA_ACCESS_CURRENT;
pgtha.flag1 = PGTHA_FLAG_PROCESS_DATA;
GETTHENT(&inputSize, &input, &outputSize, &output, &ret, &retCode, &reasonCode);
if (OMRPORT_SYSINFO_GETTHENT_ERROR == ret) {
Trc_PRT_sysinfo_get_process_start_time_getthent_error((unsigned long long)pid);
goto done;
}
dataOffset = *((unsigned int *)processData.pgthb.offc);
dataOffset = (dataOffset & I_32_MAX) >> 8;
currentProcessInfo = (pgthc *)(((char *)&processData) + dataOffset);
processStartTimeInNanoseconds = (uint64_t)currentProcessInfo->starttime * OMRPORT_TIME_DELTA_IN_NANOSECONDS;
#else /* defined(J9ZOS390) */
portLibrary->nls_printf(
portLibrary,
J9NLS_WARNING,
J9NLS_PORT_SYSINFO_UNSUPPORTED_PLATFORM_ERROR,
"omrsysinfo_get_process_start_time is unsupported on this platform.");
#endif /* defined(LINUX) */
}
done:
Trc_PRT_sysinfo_get_process_start_time_exit((unsigned long long)pid);
return processStartTimeInNanoseconds;
}
31 changes: 31 additions & 0 deletions port/win32/omrsysinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
#include "ut_omrport.h"
#include "omrsysinfo_helpers.h"

#define OMRPORT_SYSINFO_WINDOWS_TICK 10000000ULL
#define OMRPORT_SYSINFO_SEC_TO_UNIX_EPOCH 11644473600ULL
#define OMRPORT_SYSINFO_NS100_PER_SEC 10000000ULL

static int32_t copyEnvToBuffer(struct OMRPortLibrary *portLibrary, void *args);

typedef struct CopyEnvToBufferArgs {
Expand Down Expand Up @@ -1990,3 +1994,30 @@ omrsysinfo_cgroup_subsystem_iterator_destroy(struct OMRPortLibrary *portLibrary,
return;
}

uint64_t
omrsysinfo_get_process_start_time(struct OMRPortLibrary *portLibrary, uintptr_t pid)
{
Trc_PRT_sysinfo_get_process_start_time_enter((unsigned long long)pid);
uint64_t processStartTimeInNanoseconds = 0;
if (0 != omrsysinfo_process_exists(portLibrary, pid)) {
double seconds = 0;
FILETIME createTime, exitTime, kernelTime, userTime;
HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)pid);
if (NULL == process) {
Trc_PRT_sysinfo_get_process_start_time_OpenProcess_error((unsigned long long)pid);
goto done;
}
if (!GetProcessTimes(process, &createTime, &exitTime, &kernelTime, &userTime)) {
Trc_PRT_sysinfo_get_process_start_time_GetProcessTimes_error((unsigned long long)pid);
goto cleanup;
}
seconds = (double)(*(LONGLONG*)&(createTime)) / OMRPORT_SYSINFO_WINDOWS_TICK;
processStartTimeInNanoseconds = (uint64_t)((seconds - OMRPORT_SYSINFO_SEC_TO_UNIX_EPOCH) * OMRPORT_SYSINFO_NS100_PER_SEC);
processStartTimeInNanoseconds *= 100;
cleanup:
CloseHandle(process);
}
done:
Trc_PRT_sysinfo_get_process_start_time_exit((unsigned long long)pid);
return processStartTimeInNanoseconds;
}
2 changes: 1 addition & 1 deletion port/win32/omrtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ omrtime_nano_time(struct OMRPortLibrary *portLibrary)
if (PPG_time_hiresClockFrequency == OMRTIME_NANOSECONDS_PER_SECOND) {
nanos = ticks;
} else if (PPG_time_hiresClockFrequency < OMRTIME_NANOSECONDS_PER_SECOND) {
nanos = (int64_t)(ticks * (OMRTIME_NANOSECONDS_PER_SECOND / PPG_time_hiresClockFrequency));
nanos = (int64_t)(ticks * (OMRPORT_TIME_DELTA_IN_NANOSECONDS / PPG_time_hiresClockFrequency));
} else {
nanos = (int64_t)(ticks / (PPG_time_hiresClockFrequency / OMRTIME_NANOSECONDS_PER_SECOND));
}
Expand Down
Loading

0 comments on commit 403d584

Please sign in to comment.