diff options
author | Ben Gamari <ben@smart-cactus.org> | 2019-05-17 15:40:26 -0400 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-03-05 14:53:12 -0500 |
commit | cedd6f3041de6abe64dfa3257bec7730a9dced9f (patch) | |
tree | d4df43117c979edf713b220e7ecfa68bd731c37a /rts/posix | |
parent | 8c663c2c2ff0d79b2c7cfadb0ce961339f1e7e4c (diff) | |
download | haskell-cedd6f3041de6abe64dfa3257bec7730a9dced9f.tar.gz |
rts: Add getCurrentThreadCPUTime helper
Diffstat (limited to 'rts/posix')
-rw-r--r-- | rts/posix/GetTime.c | 77 |
1 files changed, 56 insertions, 21 deletions
diff --git a/rts/posix/GetTime.c b/rts/posix/GetTime.c index 8d20d18bfb..1c77708131 100644 --- a/rts/posix/GetTime.c +++ b/rts/posix/GetTime.c @@ -44,11 +44,61 @@ void initializeTimer() #endif } +#if defined(HAVE_CLOCK_GETTIME) +static Time getClockTime(clockid_t clock) +{ + struct timespec ts; + int res = clock_gettime(clock, &ts); + if (res == 0) { + return SecondsToTime(ts.tv_sec) + NSToTime(ts.tv_nsec); + } else { + sysErrorBelch("clock_gettime"); + stg_exit(EXIT_FAILURE); + } +} +#endif + +Time getCurrentThreadCPUTime(void) +{ +#if defined(HAVE_CLOCK_GETTIME) && \ + defined(CLOCK_PROCESS_CPUTIME_ID) && \ + defined(HAVE_SYSCONF) + static bool have_checked_usability = false; + if (!have_checked_usability) { + // The Linux clock_getres(2) manpage claims that some early versions of + // Linux will return values which are uninterpretable in the presence + // of migration across CPUs. They claim that clock_getcpuclockid(0) + // will return ENOENT in this case. Check this. + clockid_t clkid; + if (clock_getcpuclockid(0, &clkid)) { + sysErrorBelch("getCurrentThreadCPUTime: no supported"); + stg_exit(EXIT_FAILURE); + } + have_checked_usability = true; + } + return getClockTime(CLOCK_THREAD_CPUTIME_ID); +#elif defined(darwin_HOST_OS) + mach_port_t port = pthread_mach_thread_np(osThreadId()); + thread_basic_info_data_t info = { 0 }; + mach_msg_type_number_t info_count = THREAD_BASIC_INFO_COUNT; + kern_return_t kern_err = thread_info(mach_thread_self(), THREAD_BASIC_INFO, + (thread_info_t) &info, &info_count); + if (kern_err == KERN_SUCCESS) { + return SecondsToTime(info.user_time.seconds) + USToTime(info.user_time.microseconds); + } else { + sysErrorBelch("getThreadCPUTime"); + stg_exit(EXIT_FAILURE); + } +#else +#error I know of no means to find the CPU time of current thread on this platform. +#endif +} + Time getProcessCPUTime(void) { #if !defined(BE_CONSERVATIVE) && \ defined(HAVE_CLOCK_GETTIME) && \ - defined(_SC_CPUTIME) && \ + defined(_SC_CPUTIME) && \ defined(CLOCK_PROCESS_CPUTIME_ID) && \ defined(HAVE_SYSCONF) static int checked_sysconf = 0; @@ -59,15 +109,7 @@ Time getProcessCPUTime(void) checked_sysconf = 1; } if (sysconf_result != -1) { - struct timespec ts; - int res; - res = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts); - if (res == 0) { - return SecondsToTime(ts.tv_sec) + NSToTime(ts.tv_nsec); - } else { - sysErrorBelch("clock_gettime"); - stg_exit(EXIT_FAILURE); - } + return getClockTime(CLOCK_PROCESS_CPUTIME_ID); } #endif @@ -82,16 +124,7 @@ Time getProcessCPUTime(void) StgWord64 getMonotonicNSec(void) { #if defined(HAVE_CLOCK_GETTIME) - struct timespec ts; - int res; - - res = clock_gettime(CLOCK_ID, &ts); - if (res != 0) { - sysErrorBelch("clock_gettime"); - stg_exit(EXIT_FAILURE); - } - return (StgWord64)ts.tv_sec * 1000000000 + - (StgWord64)ts.tv_nsec; + return getClockTime(CLOCK_ID); #elif defined(darwin_HOST_OS) @@ -102,7 +135,9 @@ StgWord64 getMonotonicNSec(void) struct timeval tv; - gettimeofday(&tv, (struct timezone *) NULL); + if (gettimeofday(&tv, (struct timezone *) NULL) != 0) { + debugBlech("getMonotonicNSec: gettimeofday failed: %s", strerror(errno)); + }; return (StgWord64)tv.tv_sec * 1000000000 + (StgWord64)tv.tv_usec * 1000; |