diff options
author | Ben Gamari <ben@smart-cactus.org> | 2020-03-09 19:33:41 -0400 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-03-11 00:14:59 -0400 |
commit | bb586f894532baf1bcb822afd0df7f9fea198671 (patch) | |
tree | 9f4d26d1ab4c876f383f658db364654ef6a64310 | |
parent | abf5736bcad2d740b5854e2e4a9b3547b9b06639 (diff) | |
download | haskell-bb586f894532baf1bcb822afd0df7f9fea198671.tar.gz |
rts: Prefer darwin-specific getCurrentThreadCPUTime
macOS Catalina now supports a non-POSIX-compliant version of clock_gettime
which cannot use the clock_gettime codepath.
Fixes #17906.
-rw-r--r-- | rts/posix/GetTime.c | 40 |
1 files changed, 25 insertions, 15 deletions
diff --git a/rts/posix/GetTime.c b/rts/posix/GetTime.c index 1c77708131..eda18e1202 100644 --- a/rts/posix/GetTime.c +++ b/rts/posix/GetTime.c @@ -25,18 +25,25 @@ #error No implementation for getProcessCPUTime() available. #endif +#if defined(darwin_HOST_OS) +#include <mach/mach_time.h> +#include <mach/mach_init.h> +#include <mach/thread_act.h> +#include <mach/mach_port.h> +#endif + #if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_GETRUSAGE) // we'll implement getProcessCPUTime() and getProcessElapsedTime() // separately, using getrusage() and gettimeofday() respectively -#if !defined(HAVE_CLOCK_GETTIME) && defined(darwin_HOST_OS) +#if defined(darwin_HOST_OS) static uint64_t timer_scaling_factor_numer = 0; static uint64_t timer_scaling_factor_denom = 0; #endif void initializeTimer() { -#if !defined(HAVE_CLOCK_GETTIME) && defined(darwin_HOST_OS) +#if defined(darwin_HOST_OS) mach_timebase_info_data_t info; (void) mach_timebase_info(&info); timer_scaling_factor_numer = (uint64_t)info.numer; @@ -60,7 +67,22 @@ static Time getClockTime(clockid_t clock) Time getCurrentThreadCPUTime(void) { -#if defined(HAVE_CLOCK_GETTIME) && \ + // N.B. Since macOS Catalina, Darwin supports clock_gettime but does not + // support clock_getcpuclockid. Hence we prefer to use the Darwin-specific + // path on Darwin, even if clock_gettime is available. +#if 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); + } +#elif defined(HAVE_CLOCK_GETTIME) && \ defined(CLOCK_PROCESS_CPUTIME_ID) && \ defined(HAVE_SYSCONF) static bool have_checked_usability = false; @@ -77,18 +99,6 @@ Time getCurrentThreadCPUTime(void) 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 |