Skip to content

Commit

Permalink
Add omrthread_get_thread_times()
Browse files Browse the repository at this point in the history
This function returns the user and system cpu time of the calling
thread. This new function is needed so we can get both user time and
system time using only one system call.

Related: eclipse-openj9/openj9#20186

Signed-off-by: Gengchen Tuo <[email protected]>
  • Loading branch information
thallium committed Oct 21, 2024
1 parent d68a419 commit 3e4e6af
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
14 changes: 14 additions & 0 deletions include_core/thread_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ typedef struct omrthread_process_time_t {
int64_t _userTime;
} omrthread_process_time_t;

typedef struct omrthread_thread_time_t {
int64_t userTime;
int64_t sysTime;
} omrthread_thread_time_t;

typedef struct omrthread_state_t {
uintptr_t flags;
omrthread_monitor_t blocker;
Expand Down Expand Up @@ -1240,6 +1245,15 @@ omrthread_get_jvm_cpu_usage_info(J9ThreadsCpuUsage *cpuUsage);
void
omrthread_get_jvm_cpu_usage_info_error_recovery(void);

/**
* Gets the system and user CPU time of the current thread.
*
* @param[out] threadTime the pointer to the thread time structure
* @return 0 on success or -1 on failure
*/
intptr_t
omrthread_get_thread_times(omrthread_thread_time_t *threadTime);

/* ---------------- omrthreadattr.c ---------------- */

/**
Expand Down
69 changes: 69 additions & 0 deletions thread/common/thrprof.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
* APIs for querying per-thread statistics: CPU usage, stack usage.
*/

#if defined(LINUX)
#define _GNU_SOURCE
#include <sys/resource.h>
#endif /* defined(LINUX) */

#include <string.h> /* for memset() */
#include "omrcfg.h"

Expand Down Expand Up @@ -1025,3 +1030,67 @@ omrthread_get_jvm_cpu_usage_info_error_recovery(void)
GLOBAL_UNLOCK_SIMPLE(lib);
}
}

intptr_t
omrthread_get_thread_times(omrthread_thread_time_t *threadTime)
{
#if defined(LINUX)
struct rusage rUsage;
memset(&rUsage, 0, sizeof(rUsage));

if (0 == getrusage(RUSAGE_THREAD, &rUsage)) {
threadTime->userTime = (SEC_TO_NANO_CONVERSION_CONSTANT * (int64_t)rUsage.ru_utime.tv_sec)
+ (MICRO_TO_NANO_CONVERSION_CONSTANT * (int64_t)rUsage.ru_utime.tv_usec);
threadTime->sysTime = (SEC_TO_NANO_CONVERSION_CONSTANT * (int64_t)rUsage.ru_stime.tv_sec)
+ (MICRO_TO_NANO_CONVERSION_CONSTANT * (int64_t)rUsage.ru_stime.tv_usec);

return 0;
}

return -1;
#elif defined(OMR_OS_WINDOWS) && !defined(BREW) /* defined(LINUX) */
omrthread_t self = omrthread_self();
FILETIME creationTime;
FILETIME exitTime;
FILETIME kernelTime;
FILETIME userTime;
memset(&creationTime, 0, sizeof(creationTime));
memset(&exitTime, 0, sizeof(exitTime));
memset(&kernelTime, 0, sizeof(kernelTime));
memset(&userTime, 0, sizeof(userTime));

if (GetThreadTimes(self->handle, &creationTime, &exitTime, &kernelTime, &userTime)) {
/* 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;

return 0;
}

return -1;
#elif defined(AIXPPC) /* defined(OMR_OS_WINDOWS) && !defined(BREW) */
omrthread_t self = omrthread_self();

/* AIX provides a function call that returns an entire structure of
* information about the thread.
*/
struct rusage rUsage;
memset(&rUsage, 0, sizeof(rUsage));

if (0 == pthread_getrusage_np(self->handle, &rUsage, PTHRDSINFO_RUSAGE_COLLECT)) {
threadTime->userTime = (SEC_TO_NANO_CONVERSION_CONSTANT * (int64_t)rUsage.ru_utime.tv_sec)
+ (MICRO_TO_NANO_CONVERSION_CONSTANT * (int64_t)rUsage.ru_utime.tv_usec);
threadTime->sysTime = (SEC_TO_NANO_CONVERSION_CONSTANT * (int64_t)rUsage.ru_stime.tv_sec)
+ (MICRO_TO_NANO_CONVERSION_CONSTANT * (int64_t)rUsage.ru_stime.tv_usec);
return 0;
}

return -1;
#else /* defined(AIXPPC) */

/* Currently getting user time is only supported on Windows, Linux, and AIX, so
* we can just return -1.
*/
return -1;
#endif /* defined(LINUX) */
}

0 comments on commit 3e4e6af

Please sign in to comment.