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/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
23namespace LIBC_NAMESPACE_DECL {
24namespace internal {
25ErrorOr<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
63

source code of libc/src/__support/time/linux/clock_gettime.cpp