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 22, 2024
1 parent d68a419 commit dbd3fb1
Show file tree
Hide file tree
Showing 2 changed files with 80 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
66 changes: 66 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,64 @@ 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) */
/* Return -1 since the user time can only be retrieved on Windows, Linux, and AIX. */
return -1;
#endif /* defined(LINUX) */
}

0 comments on commit dbd3fb1

Please sign in to comment.