diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -2229,8 +2229,20 @@ return res; } -#define INIT_CLOCK_GETCPUCLOCKID \ - COMMON_INTERCEPT_FUNCTION(clock_getcpuclockid); +INTERCEPTOR(int, pthread_getcpuclockid, uptr thread, + __sanitizer_clockid_t *clockid) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, pthread_getcpuclockid, thread, clockid); + int res = REAL(pthread_getcpuclockid)(thread, clockid); + if (!res && clockid) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, clockid, sizeof *clockid); + } + return res; +} + +#define INIT_CLOCK_GETCPUCLOCKID \ + COMMON_INTERCEPT_FUNCTION(clock_getcpuclockid); \ + COMMON_INTERCEPT_FUNCTION(pthread_getcpuclockid); #else #define INIT_CLOCK_GETCPUCLOCKID #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -229,7 +229,7 @@ (SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_CLOCK_GETTIME \ (SI_FREEBSD || SI_NETBSD || SI_LINUX || SI_SOLARIS) -#define SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID SI_LINUX +#define SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID (SI_LINUX || SI_FREEBSD) #define SANITIZER_INTERCEPT_GETITIMER SI_POSIX #define SANITIZER_INTERCEPT_TIME SI_POSIX #define SANITIZER_INTERCEPT_GLOB (SI_GLIBC || SI_SOLARIS) diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/getcpuclockid.c b/compiler-rt/test/sanitizer_common/TestCases/Linux/getcpuclockid.c --- a/compiler-rt/test/sanitizer_common/TestCases/Linux/getcpuclockid.c +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/getcpuclockid.c @@ -1,20 +0,0 @@ -// RUN: %clang %s -Wl,-as-needed -o %t && %run %t -#include -#include -#include - -long cpu_ns() { - clockid_t clk; - struct timespec ts; - int res = clock_getcpuclockid(getpid(), &clk); - assert(!res); - res = clock_gettime(clk, &ts); - assert(!res); - return ts.tv_nsec; -} - -int main() { - long cpuns = cpu_ns(); - asm volatile ("" :: "r"(cpuns)); - return 0; -} diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/getcpuclockid.c b/compiler-rt/test/sanitizer_common/TestCases/Posix/getcpuclockid.c new file mode 100644 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/getcpuclockid.c @@ -0,0 +1,36 @@ +// RUN: %clang -pthread %s -Wl,-as-needed -o %t && %run %t +// +// UNSUPPORTED: darwin, netbsd, solaris + +#include +#include +#include +#include + +long cpu_ns() { + clockid_t clk; + struct timespec ts; + int res = clock_getcpuclockid(getpid(), &clk); + assert(!res); + res = clock_gettime(clk, &ts); + assert(!res); + return ts.tv_nsec; +} + +long th_cpu_ns() { + clockid_t clk; + struct timespec ts; + int res = pthread_getcpuclockid(pthread_self(), &clk); + assert(!res); + res = clock_gettime(clk, &ts); + assert(!res); + return ts.tv_nsec; +} + +int main() { + long cpuns = cpu_ns(); + asm volatile ("" :: "r"(cpuns)); + cpuns = th_cpu_ns(); + asm volatile ("" :: "r"(cpuns)); + return 0; +}