11b413c8aSSchrodinger ZHU Yifan //===--- clock_gettime linux implementation ---------------------*- C++ -*-===// 21b413c8aSSchrodinger ZHU Yifan // 31b413c8aSSchrodinger ZHU Yifan // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 41b413c8aSSchrodinger ZHU Yifan // See https://llvm.org/LICENSE.txt for license information. 51b413c8aSSchrodinger ZHU Yifan // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 61b413c8aSSchrodinger ZHU Yifan // 71b413c8aSSchrodinger ZHU Yifan //===----------------------------------------------------------------------===// 81b413c8aSSchrodinger ZHU Yifan 9*e6cf5d28SSchrodinger ZHU Yifan #include "src/__support/time/clock_gettime.h" 101b413c8aSSchrodinger ZHU Yifan #include "hdr/types/clockid_t.h" 111b413c8aSSchrodinger ZHU Yifan #include "hdr/types/struct_timespec.h" 121b413c8aSSchrodinger ZHU Yifan #include "src/__support/OSUtil/linux/vdso.h" 131b413c8aSSchrodinger ZHU Yifan #include "src/__support/OSUtil/syscall.h" 141b413c8aSSchrodinger ZHU Yifan #include "src/__support/common.h" 151b413c8aSSchrodinger ZHU Yifan #include "src/__support/error_or.h" 161b413c8aSSchrodinger ZHU Yifan #include "src/__support/macros/config.h" 171b413c8aSSchrodinger ZHU Yifan #include <sys/syscall.h> 181b413c8aSSchrodinger ZHU Yifan 191b413c8aSSchrodinger ZHU Yifan #if defined(SYS_clock_gettime64) 201b413c8aSSchrodinger ZHU Yifan #include <linux/time_types.h> 211b413c8aSSchrodinger ZHU Yifan #endif 221b413c8aSSchrodinger ZHU Yifan 231b413c8aSSchrodinger ZHU Yifan namespace LIBC_NAMESPACE_DECL { 241b413c8aSSchrodinger ZHU Yifan namespace internal { 251b413c8aSSchrodinger ZHU Yifan ErrorOr<int> clock_gettime(clockid_t clockid, timespec *ts) { 261b413c8aSSchrodinger ZHU Yifan using namespace vdso; 271b413c8aSSchrodinger ZHU Yifan int ret; 281b413c8aSSchrodinger ZHU Yifan #if defined(SYS_clock_gettime) 291b413c8aSSchrodinger ZHU Yifan TypedSymbol<VDSOSym::ClockGetTime> clock_gettime; 301b413c8aSSchrodinger ZHU Yifan if (LIBC_LIKELY(clock_gettime != nullptr)) 311b413c8aSSchrodinger ZHU Yifan ret = clock_gettime(clockid, ts); 321b413c8aSSchrodinger ZHU Yifan else 331b413c8aSSchrodinger ZHU Yifan ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_gettime, 341b413c8aSSchrodinger ZHU Yifan static_cast<long>(clockid), 351b413c8aSSchrodinger ZHU Yifan reinterpret_cast<long>(ts)); 361b413c8aSSchrodinger ZHU Yifan #elif defined(SYS_clock_gettime64) 371b413c8aSSchrodinger ZHU Yifan static_assert( 381b413c8aSSchrodinger ZHU Yifan sizeof(time_t) == sizeof(int64_t), 391b413c8aSSchrodinger ZHU Yifan "SYS_clock_gettime64 requires struct timespec with 64-bit members."); 401b413c8aSSchrodinger ZHU Yifan 411b413c8aSSchrodinger ZHU Yifan TypedSymbol<VDSOSym::ClockGetTime64> clock_gettime64; 421b413c8aSSchrodinger ZHU Yifan __kernel_timespec ts64{}; 431b413c8aSSchrodinger ZHU Yifan if (LIBC_LIKELY(clock_gettime64 != nullptr)) 441b413c8aSSchrodinger ZHU Yifan ret = clock_gettime64(clockid, &ts64); 451b413c8aSSchrodinger ZHU Yifan else 461b413c8aSSchrodinger ZHU Yifan ret = LIBC_NAMESPACE::syscall_impl<int>(SYS_clock_gettime64, 471b413c8aSSchrodinger ZHU Yifan static_cast<long>(clockid), 481b413c8aSSchrodinger ZHU Yifan reinterpret_cast<long>(&ts64)); 491b413c8aSSchrodinger ZHU Yifan if (ret == 0) { 501b413c8aSSchrodinger ZHU Yifan ts->tv_sec = static_cast<decltype(ts->tv_sec)>(ts64.tv_sec); 511b413c8aSSchrodinger ZHU Yifan ts->tv_nsec = static_cast<decltype(ts->tv_nsec)>(ts64.tv_nsec); 521b413c8aSSchrodinger ZHU Yifan } 531b413c8aSSchrodinger ZHU Yifan #else 541b413c8aSSchrodinger ZHU Yifan #error "SYS_clock_gettime and SYS_clock_gettime64 syscalls not available." 551b413c8aSSchrodinger ZHU Yifan #endif 561b413c8aSSchrodinger ZHU Yifan if (ret < 0) 571b413c8aSSchrodinger ZHU Yifan return Error(-ret); 581b413c8aSSchrodinger ZHU Yifan return ret; 591b413c8aSSchrodinger ZHU Yifan } 601b413c8aSSchrodinger ZHU Yifan 611b413c8aSSchrodinger ZHU Yifan } // namespace internal 621b413c8aSSchrodinger ZHU Yifan } // namespace LIBC_NAMESPACE_DECL 63