Skip to content

Commit 1b413c8

Browse files
[libc] fix clock_gettime symbols being undefined (#117224)
`clock_gettime` being a header library discards the dependency chain behind it.
1 parent 9492744 commit 1b413c8

File tree

3 files changed

+66
-42
lines changed

3 files changed

+66
-42
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
add_header_library(
1+
add_object_library(
22
clock_gettime
33
HDRS
44
clock_gettime.h
5+
SRCS
6+
clock_gettime.cpp
57
DEPENDS
68
libc.include.sys_syscall
79
libc.hdr.types.struct_timespec
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//===--- clock_gettime linux implementation ---------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/__support/time/linux/clock_gettime.h"
10+
#include "hdr/types/clockid_t.h"
11+
#include "hdr/types/struct_timespec.h"
12+
#include "src/__support/OSUtil/linux/vdso.h"
13+
#include "src/__support/OSUtil/syscall.h"
14+
#include "src/__support/common.h"
15+
#include "src/__support/error_or.h"
16+
#include "src/__support/macros/config.h"
17+
#include <sys/syscall.h>
18+
19+
#if defined(SYS_clock_gettime64)
20+
#include <linux/time_types.h>
21+
#endif
22+
23+
namespace LIBC_NAMESPACE_DECL {
24+
namespace internal {
25+
ErrorOr<int> clock_gettime(clockid_t clockid, timespec *ts) {
26+
using namespace vdso;
27+
int ret;
28+
#if defined(SYS_clock_gettime)
29+
TypedSymbol<VDSOSym::ClockGetTime> clock_gettime;
30+
if (LIBC_LIKELY(clock_gettime != nullptr))
31+
ret = clock_gettime(clockid, ts);
32+
else
33+
ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_gettime,
34+
static_cast<long>(clockid),
35+
reinterpret_cast<long>(ts));
36+
#elif defined(SYS_clock_gettime64)
37+
static_assert(
38+
sizeof(time_t) == sizeof(int64_t),
39+
"SYS_clock_gettime64 requires struct timespec with 64-bit members.");
40+
41+
TypedSymbol<VDSOSym::ClockGetTime64> clock_gettime64;
42+
__kernel_timespec ts64{};
43+
if (LIBC_LIKELY(clock_gettime64 != nullptr))
44+
ret = clock_gettime64(clockid, &ts64);
45+
else
46+
ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_gettime64,
47+
static_cast<long>(clockid),
48+
reinterpret_cast<long>(&ts64));
49+
if (ret == 0) {
50+
ts->tv_sec = static_cast<decltype(ts->tv_sec)>(ts64.tv_sec);
51+
ts->tv_nsec = static_cast<decltype(ts->tv_nsec)>(ts64.tv_nsec);
52+
}
53+
#else
54+
#error "SYS_clock_gettime and SYS_clock_gettime64 syscalls not available."
55+
#endif
56+
if (ret < 0)
57+
return Error(-ret);
58+
return ret;
59+
}
60+
61+
} // namespace internal
62+
} // namespace LIBC_NAMESPACE_DECL

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

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,55 +11,15 @@
1111

1212
#include "hdr/types/clockid_t.h"
1313
#include "hdr/types/struct_timespec.h"
14-
#include "src/__support/OSUtil/linux/vdso.h"
15-
#include "src/__support/OSUtil/syscall.h"
16-
#include "src/__support/common.h"
1714
#include "src/__support/error_or.h"
18-
#include "src/__support/macros/config.h"
19-
#include <sys/syscall.h>
2015

2116
#if defined(SYS_clock_gettime64)
2217
#include <linux/time_types.h>
2318
#endif
2419

2520
namespace LIBC_NAMESPACE_DECL {
2621
namespace internal {
27-
LIBC_INLINE ErrorOr<int> clock_gettime(clockid_t clockid, timespec *ts) {
28-
using namespace vdso;
29-
int ret;
30-
#if defined(SYS_clock_gettime)
31-
TypedSymbol<VDSOSym::ClockGetTime> clock_gettime;
32-
if (LIBC_LIKELY(clock_gettime != nullptr))
33-
ret = clock_gettime(clockid, ts);
34-
else
35-
ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_gettime,
36-
static_cast<long>(clockid),
37-
reinterpret_cast<long>(ts));
38-
#elif defined(SYS_clock_gettime64)
39-
static_assert(
40-
sizeof(time_t) == sizeof(int64_t),
41-
"SYS_clock_gettime64 requires struct timespec with 64-bit members.");
42-
43-
TypedSymbol<VDSOSym::ClockGetTime64> clock_gettime64;
44-
__kernel_timespec ts64{};
45-
if (LIBC_LIKELY(clock_gettime64 != nullptr))
46-
ret = clock_gettime64(clockid, &ts64);
47-
else
48-
ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_gettime64,
49-
static_cast<long>(clockid),
50-
reinterpret_cast<long>(&ts64));
51-
if (ret == 0) {
52-
ts->tv_sec = static_cast<decltype(ts->tv_sec)>(ts64.tv_sec);
53-
ts->tv_nsec = static_cast<decltype(ts->tv_nsec)>(ts64.tv_nsec);
54-
}
55-
#else
56-
#error "SYS_clock_gettime and SYS_clock_gettime64 syscalls not available."
57-
#endif
58-
if (ret < 0)
59-
return Error(-ret);
60-
return ret;
61-
}
62-
22+
ErrorOr<int> clock_gettime(clockid_t clockid, timespec *ts);
6323
} // namespace internal
6424
} // namespace LIBC_NAMESPACE_DECL
6525

0 commit comments

Comments
 (0)