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 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 63