|
28 | 28 | * APIs for querying per-thread statistics: CPU usage, stack usage.
|
29 | 29 | */
|
30 | 30 |
|
| 31 | +#if defined(LINUX) |
| 32 | +#define _GNU_SOURCE |
| 33 | +#include <sys/resource.h> |
| 34 | +#endif /* defined(LINUX) */ |
| 35 | + |
31 | 36 | #include <string.h> /* for memset() */
|
32 | 37 | #include "omrcfg.h"
|
33 | 38 |
|
@@ -1025,3 +1030,64 @@ omrthread_get_jvm_cpu_usage_info_error_recovery(void)
|
1025 | 1030 | GLOBAL_UNLOCK_SIMPLE(lib);
|
1026 | 1031 | }
|
1027 | 1032 | }
|
| 1033 | + |
| 1034 | +intptr_t |
| 1035 | +omrthread_get_thread_times(omrthread_thread_time_t *threadTime) |
| 1036 | +{ |
| 1037 | +#if defined(LINUX) |
| 1038 | + struct rusage rUsage; |
| 1039 | + memset(&rUsage, 0, sizeof(rUsage)); |
| 1040 | + |
| 1041 | + if (0 == getrusage(RUSAGE_THREAD, &rUsage)) { |
| 1042 | + threadTime->userTime = (SEC_TO_NANO_CONVERSION_CONSTANT * (int64_t)rUsage.ru_utime.tv_sec) |
| 1043 | + + (MICRO_TO_NANO_CONVERSION_CONSTANT * (int64_t)rUsage.ru_utime.tv_usec); |
| 1044 | + threadTime->sysTime = (SEC_TO_NANO_CONVERSION_CONSTANT * (int64_t)rUsage.ru_stime.tv_sec) |
| 1045 | + + (MICRO_TO_NANO_CONVERSION_CONSTANT * (int64_t)rUsage.ru_stime.tv_usec); |
| 1046 | + |
| 1047 | + return 0; |
| 1048 | + } |
| 1049 | + |
| 1050 | + return -1; |
| 1051 | +#elif defined(OMR_OS_WINDOWS) && !defined(BREW) /* defined(LINUX) */ |
| 1052 | + omrthread_t self = omrthread_self(); |
| 1053 | + FILETIME creationTime; |
| 1054 | + FILETIME exitTime; |
| 1055 | + FILETIME kernelTime; |
| 1056 | + FILETIME userTime; |
| 1057 | + memset(&creationTime, 0, sizeof(creationTime)); |
| 1058 | + memset(&exitTime, 0, sizeof(exitTime)); |
| 1059 | + memset(&kernelTime, 0, sizeof(kernelTime)); |
| 1060 | + memset(&userTime, 0, sizeof(userTime)); |
| 1061 | + |
| 1062 | + if (GetThreadTimes(self->handle, &creationTime, &exitTime, &kernelTime, &userTime)) { |
| 1063 | + /* Time is in 100's of nanos. Convert to nanos. */ |
| 1064 | + threadTime->sysTime = ((int64_t)kernelTime.dwLowDateTime | ((int64_t)kernelTime.dwHighDateTime << 32)) * 100; |
| 1065 | + threadTime->userTime = ((int64_t)userTime.dwLowDateTime | ((int64_t)userTime.dwHighDateTime << 32)) * 100; |
| 1066 | + |
| 1067 | + return 0; |
| 1068 | + } |
| 1069 | + |
| 1070 | + return -1; |
| 1071 | +#elif defined(AIXPPC) /* defined(OMR_OS_WINDOWS) && !defined(BREW) */ |
| 1072 | + omrthread_t self = omrthread_self(); |
| 1073 | + |
| 1074 | + /* AIX provides a function call that returns an entire structure of |
| 1075 | + * information about the thread. |
| 1076 | + */ |
| 1077 | + struct rusage rUsage; |
| 1078 | + memset(&rUsage, 0, sizeof(rUsage)); |
| 1079 | + |
| 1080 | + if (0 == pthread_getrusage_np(self->handle, &rUsage, PTHRDSINFO_RUSAGE_COLLECT)) { |
| 1081 | + threadTime->userTime = (SEC_TO_NANO_CONVERSION_CONSTANT * (int64_t)rUsage.ru_utime.tv_sec) |
| 1082 | + + (MICRO_TO_NANO_CONVERSION_CONSTANT * (int64_t)rUsage.ru_utime.tv_usec); |
| 1083 | + threadTime->sysTime = (SEC_TO_NANO_CONVERSION_CONSTANT * (int64_t)rUsage.ru_stime.tv_sec) |
| 1084 | + + (MICRO_TO_NANO_CONVERSION_CONSTANT * (int64_t)rUsage.ru_stime.tv_usec); |
| 1085 | + return 0; |
| 1086 | + } |
| 1087 | + |
| 1088 | + return -1; |
| 1089 | +#else /* defined(AIXPPC) */ |
| 1090 | + /* Return -1 since the user time can only be retrieved on Windows, Linux, and AIX. */ |
| 1091 | + return -1; |
| 1092 | +#endif /* defined(LINUX) */ |
| 1093 | +} |
0 commit comments