Skip to content

Commit 6573c16

Browse files
[libc] update clock_gettime implementation with vDSO
1 parent e3212e7 commit 6573c16

File tree

3 files changed

+23
-10
lines changed

3 files changed

+23
-10
lines changed

libc/src/__support/time/linux/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ add_object_library(
1111
libc.src.__support.common
1212
libc.src.__support.error_or
1313
libc.src.__support.OSUtil.osutil
14+
libc.src.__support.OSUtil.vdso
1415
)

libc/src/__support/time/linux/clock_gettime.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,37 @@
88

99
#include "src/__support/time/linux/clock_gettime.h"
1010
#include "src/__support/OSUtil/syscall.h"
11+
#include "src/__support/OSUtil/vdso.h"
1112
#include <sys/syscall.h>
1213
namespace LIBC_NAMESPACE {
1314
namespace internal {
1415
ErrorOr<int> clock_gettime(clockid_t clockid, timespec *ts) {
16+
int ret;
17+
do {
18+
#ifdef LIBC_VDSO_HAS_CLOCK_GETTIME
19+
if (void *symbol = vdso::get_symbol(vdso::VDSOSym::ClockGetTime)) {
20+
using FuncTy = int (*)(clockid_t, timespec *);
21+
auto func = reinterpret_cast<FuncTy>(symbol);
22+
ret = func(clockid, ts);
23+
break;
24+
}
25+
#endif
1526
#if SYS_clock_gettime
16-
int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_gettime,
17-
static_cast<long>(clockid),
18-
reinterpret_cast<long>(ts));
27+
ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_gettime,
28+
static_cast<long>(clockid),
29+
reinterpret_cast<long>(ts));
1930
#elif defined(SYS_clock_gettime64)
20-
static_assert(
21-
sizeof(time_t) == sizeof(int64_t),
22-
"SYS_clock_gettime64 requires struct timespec with 64-bit members.");
23-
int ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_gettime64,
24-
static_cast<long>(clockid),
25-
reinterpret_cast<long>(ts));
31+
static_assert(
32+
sizeof(time_t) == sizeof(int64_t),
33+
"SYS_clock_gettime64 requires struct timespec with 64-bit members.");
34+
ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_gettime64,
35+
static_cast<long>(clockid),
36+
reinterpret_cast<long>(ts));
2637
#else
2738
#error "SYS_clock_gettime and SYS_clock_gettime64 syscalls not available."
2839
#endif
40+
} while (0);
41+
2942
if (ret < 0)
3043
return Error(-ret);
3144
return ret;

libc/src/time/linux/time.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
namespace LIBC_NAMESPACE {
1616

1717
LLVM_LIBC_FUNCTION(time_t, time, (time_t * tp)) {
18-
// TODO: Use the Linux VDSO to fetch the time and avoid the syscall.
1918
struct timespec ts;
2019
auto result = internal::clock_gettime(CLOCK_REALTIME, &ts);
2120
if (!result.has_value()) {

0 commit comments

Comments
 (0)