From f6726b65d24870a5b96cb7af8c82cc9a2c3376a8 Mon Sep 17 00:00:00 2001 From: Gengchen Tuo Date: Thu, 10 Oct 2024 11:45:49 -0400 Subject: [PATCH] Add omrthread_get_self_thread_time() This function returns the user and system cpu time of the calling thread. Related: https://github.com/eclipse-openj9/openj9/pull/20186 Signed-off-by: Gengchen Tuo --- include_core/omrport.h | 4 ++++ include_core/omrthread.h | 5 +++++ port/CMakeLists.txt | 1 + port/common/omrport.c | 1 + port/common/omrthread.c | 41 ++++++++++++++++++++++++++++++++++++++++ port/omrportpriv.h | 4 ++++ port/port_objects.mk | 2 ++ 7 files changed, 58 insertions(+) create mode 100644 port/common/omrthread.c diff --git a/include_core/omrport.h b/include_core/omrport.h index 18afbed6861..a5ad2ff9ceb 100644 --- a/include_core/omrport.h +++ b/include_core/omrport.h @@ -2757,6 +2757,8 @@ typedef struct OMRPortLibrary { /** see @ref omrcuda.cpp::omrcuda_streamWaitEvent "omrcuda_streamWaitEvent" */ int32_t (*cuda_streamWaitEvent)(struct OMRPortLibrary *portLibrary, uint32_t deviceId, J9CudaStream stream, J9CudaEvent event); #endif /* OMR_OPT_CUDA */ + /** see @ref omrthread.c::omrthread_get_self_thread_time "omrthread_get_self_thread_time" */ +int32_t (*omrthread_get_self_thread_time)(struct OMRPortLibrary *portLibrary, struct omrthread_thread_time_t *thread_time); } OMRPortLibrary; /** @@ -3339,6 +3341,8 @@ extern J9_CFUNC int32_t omrport_getVersion(struct OMRPortLibrary *portLibrary); privateOmrPortLibrary->cuda_streamWaitEvent(privateOmrPortLibrary, (deviceId), (stream), (event)) #endif /* OMR_OPT_CUDA */ +#define omrthread_get_self_thread_time(threadTime) privateOmrPortLibrary->omrthread_get_self_thread_time(privateOmrPortLibrary, (threadTime)) + #endif /* !defined(OMRPORT_LIBRARY_DEFINE) */ /** @} */ diff --git a/include_core/omrthread.h b/include_core/omrthread.h index 4110db80d58..32de3247cba 100644 --- a/include_core/omrthread.h +++ b/include_core/omrthread.h @@ -117,6 +117,11 @@ or omrthread priority value. #define omrthread_monitor_init(pMon,flags) omrthread_monitor_init_with_name(pMon,flags, #pMon) +typedef struct omrthread_thread_time_t { + int64_t userTime; + int64_t sysTime; +} omrthread_thread_time_t; + #ifdef __cplusplus } #endif diff --git a/port/CMakeLists.txt b/port/CMakeLists.txt index 86c41279291..66d46f79b4b 100644 --- a/port/CMakeLists.txt +++ b/port/CMakeLists.txt @@ -183,6 +183,7 @@ list(APPEND OBJECTS omrsignal.c omrsock.c omrsockptb.c + omrthread.c ) if(NOT OMR_OS_WINDOWS) diff --git a/port/common/omrport.c b/port/common/omrport.c index ab2319f0c1b..359a1839f75 100644 --- a/port/common/omrport.c +++ b/port/common/omrport.c @@ -476,6 +476,7 @@ static OMRPortLibrary MainPortLibraryTable = { omrcuda_streamSynchronize, /* cuda_streamSynchronize */ omrcuda_streamWaitEvent, /* cuda_streamWaitEvent */ #endif /* OMR_OPT_CUDA */ + omrthread_get_self_thread_time, }; /** diff --git a/port/common/omrthread.c b/port/common/omrthread.c new file mode 100644 index 00000000000..6d18e5be9c8 --- /dev/null +++ b/port/common/omrthread.c @@ -0,0 +1,41 @@ +#if defined (LINUX) +#define _GNU_SOURCE +#include +#endif /* defined (LINUX) */ + +#include + +#include "omrport.h" +#include "omrportpriv.h" +#include "omrthread.h" + +int32_t omrthread_get_self_thread_time(struct OMRPortLibrary *portLibrary, omrthread_thread_time_t *threadTime) { + omrthread_t self = omrthread_self(); + + int64_t cpuTime = omrthread_get_cpu_time(self); + if (-1 == cpuTime) { + return -1; + } + + #if defined (LINUX) + struct rusage rUsage = {0}; + int64_t userTime = -1; + int rc = getrusage(RUSAGE_THREAD, &rUsage); + if (0 == rc) { + 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); + } else { + userTime = rc; + } +#else /* defined (LINUX) */ + int64_t userTime = omrthread_get_user_time(self); +#endif /* defined (LINUX) */ + + if (-1 == userTime) { + return -1; + } + + threadTime->sysTime = cpuTime - userTime; + threadTime->userTime = userTime; + return 0; +} diff --git a/port/omrportpriv.h b/port/omrportpriv.h index 506e61572d3..e4387146add 100644 --- a/port/omrportpriv.h +++ b/port/omrportpriv.h @@ -1110,4 +1110,8 @@ extern J9_CFUNC int32_t omrcuda_streamWaitEvent(struct OMRPortLibrary *portLibrary, uint32_t deviceId, J9CudaStream stream, J9CudaEvent event); #endif /* OMR_OPT_CUDA */ +/* omrthread */ +extern J9_CFUNC int32_t +omrthread_get_self_thread_time(struct OMRPortLibrary *portLibrary, struct omrthread_thread_time_t *thread_time); + #endif /* omrportlibraryprivatedefines_h */ diff --git a/port/port_objects.mk b/port/port_objects.mk index bda540f28c3..a1005261dcc 100644 --- a/port/port_objects.mk +++ b/port/port_objects.mk @@ -209,6 +209,8 @@ ifeq (1,$(OMR_OPT_CUDA)) OBJECTS += omrcuda endif +OBJECTS += omrthread + # Append OBJEXT to the complete list of OBJECTS # except for .res files for windows OBJECTS := $(sort $(addsuffix $(OBJEXT),$(filter-out %.res,$(OBJECTS))) $(filter %.res,$(OBJECTS)))