diff --git a/libc/src/time/CMakeLists.txt b/libc/src/time/CMakeLists.txt index 5a0b3ab31cf0f..210f3b23432b4 100644 --- a/libc/src/time/CMakeLists.txt +++ b/libc/src/time/CMakeLists.txt @@ -35,19 +35,6 @@ add_entrypoint_object( libc.include.time ) -add_entrypoint_object( - clock_gettime - SRCS - clock_gettime.cpp - HDRS - clock_gettime.h - DEPENDS - libc.include.time - libc.include.sys_syscall - libc.src.__support.OSUtil.osutil - libc.src.errno.errno -) - add_entrypoint_object( difftime SRCS @@ -58,20 +45,6 @@ add_entrypoint_object( libc.include.time ) -add_entrypoint_object( - gettimeofday - SRCS - gettimeofday.cpp - HDRS - gettimeofday.h - DEPENDS - .clock_gettime - libc.include.time - libc.include.sys_syscall - libc.src.__support.OSUtil.osutil - libc.src.errno.errno -) - add_entrypoint_object( gmtime SRCS @@ -126,3 +99,17 @@ add_entrypoint_object( DEPENDS .${LIBC_TARGET_OS}.nanosleep ) + +add_entrypoint_object( + clock_gettime + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.clock_gettime +) + +add_entrypoint_object( + gettimeofday + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.gettimeofday +) diff --git a/libc/src/time/linux/CMakeLists.txt b/libc/src/time/linux/CMakeLists.txt index 8b4976847f82a..df79bf5986261 100644 --- a/libc/src/time/linux/CMakeLists.txt +++ b/libc/src/time/linux/CMakeLists.txt @@ -38,3 +38,29 @@ add_entrypoint_object( libc.src.__support.OSUtil.osutil libc.src.errno.errno ) + +add_entrypoint_object( + clock_gettime + SRCS + clock_gettime.cpp + HDRS + ../clock_gettime.h + DEPENDS + libc.include.time + libc.include.sys_syscall + libc.src.__support.OSUtil.osutil + libc.src.errno.errno +) + +add_entrypoint_object( + gettimeofday + SRCS + gettimeofday.cpp + HDRS + ../gettimeofday.h + DEPENDS + libc.include.time + libc.include.sys_syscall + libc.src.__support.OSUtil.osutil + libc.src.errno.errno +) diff --git a/libc/src/time/linux/clock.cpp b/libc/src/time/linux/clock.cpp index 2b19f8e9c54ce..cf27f5c299571 100644 --- a/libc/src/time/linux/clock.cpp +++ b/libc/src/time/linux/clock.cpp @@ -12,6 +12,7 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" #include "src/errno/libc_errno.h" +#include "src/time/linux/clockGetTimeImpl.h" #include // For syscall numbers. #include @@ -20,19 +21,10 @@ namespace __llvm_libc { LLVM_LIBC_FUNCTION(clock_t, clock, ()) { struct timespec ts; -#if SYS_clock_gettime - int ret = __llvm_libc::syscall_impl( - SYS_clock_gettime, CLOCK_PROCESS_CPUTIME_ID, reinterpret_cast(&ts)); -#elif defined(SYS_clock_gettime64) - int ret = __llvm_libc::syscall_impl(SYS_clock_gettime64, - CLOCK_PROCESS_CPUTIME_ID, - reinterpret_cast(&ts)); -#else -#error "SYS_clock_gettime and SYS_clock_gettime64 syscalls not available." -#endif - if (ret < 0) { - libc_errno = -ret; - return clock_t(-1); + auto result = internal::clock_gettimeimpl(CLOCK_PROCESS_CPUTIME_ID, &ts); + if (!result.has_value()) { + libc_errno = result.error(); + return -1; } // The above syscall gets the CPU time in seconds plus nanoseconds. diff --git a/libc/src/time/clock_gettime.cpp b/libc/src/time/linux/clockGetTimeImpl.h similarity index 63% rename from libc/src/time/clock_gettime.cpp rename to libc/src/time/linux/clockGetTimeImpl.h index 94818c03768cc..a5b7d659c7c14 100644 --- a/libc/src/time/clock_gettime.cpp +++ b/libc/src/time/linux/clockGetTimeImpl.h @@ -1,4 +1,4 @@ -//===---------- Linux implementation of the POSIX clock_gettime function --===// +//===- Linux implementation of the POSIX clock_gettime function -*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,40 +6,42 @@ // //===----------------------------------------------------------------------===// -#include "src/time/clock_gettime.h" +#ifndef LLVM_LIBC_SRC_TIME_LINUX_CLOCKGETTIMEIMPL_H +#define LLVM_LIBC_SRC_TIME_LINUX_CLOCKGETTIMEIMPL_H #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" +#include "src/__support/error_or.h" #include "src/errno/libc_errno.h" #include // For syscall numbers. #include namespace __llvm_libc { +namespace internal { -// TODO(michaelrj): Move this into time/linux with the other syscalls. -LLVM_LIBC_FUNCTION(int, clock_gettime, - (clockid_t clockid, struct timespec *tp)) { +LIBC_INLINE ErrorOr clock_gettimeimpl(clockid_t clockid, + struct timespec *ts) { #if SYS_clock_gettime int ret = __llvm_libc::syscall_impl(SYS_clock_gettime, static_cast(clockid), - reinterpret_cast(tp)); + reinterpret_cast(ts)); #elif defined(SYS_clock_gettime64) + struct timespec64 ts64; int ret = __llvm_libc::syscall_impl(SYS_clock_gettime64, static_cast(clockid), - reinterpret_cast(tp)); + reinterpret_cast(&ts64)); + ts->tv_sec = static_cast(ts64.tv_sec); + ts->tv_nsec = static_cast(ts64.tv_nsec); #else #error "SYS_clock_gettime and SYS_clock_gettime64 syscalls not available." #endif - - // A negative return value indicates an error with the magnitude of the - // value being the error code. - if (ret < 0) { - libc_errno = -ret; - return -1; - } - - return 0; + if (ret < 0) + return Error(-ret); + return ret; } +} // namespace internal } // namespace __llvm_libc + +#endif // LLVM_LIBC_SRC_TIME_LINUX_CLOCKGETTIMEIMPL_H diff --git a/libc/src/time/linux/clock_gettime.cpp b/libc/src/time/linux/clock_gettime.cpp new file mode 100644 index 0000000000000..33ec04eb35274 --- /dev/null +++ b/libc/src/time/linux/clock_gettime.cpp @@ -0,0 +1,35 @@ +//===---------- Linux implementation of the POSIX clock_gettime function --===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/time/clock_gettime.h" + +#include "src/__support/OSUtil/syscall.h" // For internal syscall function. +#include "src/__support/common.h" +#include "src/errno/libc_errno.h" +#include "src/time/linux/clockGetTimeImpl.h" + +#include // For syscall numbers. +#include + +namespace __llvm_libc { + +// TODO(michaelrj): Move this into time/linux with the other syscalls. +LLVM_LIBC_FUNCTION(int, clock_gettime, + (clockid_t clockid, struct timespec *ts)) { + auto result = internal::clock_gettimeimpl(clockid, ts); + + // A negative return value indicates an error with the magnitude of the + // value being the error code. + if (!result.has_value()) { + libc_errno = result.error(); + return -1; + } + return 0; +} + +} // namespace __llvm_libc diff --git a/libc/src/time/gettimeofday.cpp b/libc/src/time/linux/gettimeofday.cpp similarity index 58% rename from libc/src/time/gettimeofday.cpp rename to libc/src/time/linux/gettimeofday.cpp index 8d44e630cc13b..2df6429974164 100644 --- a/libc/src/time/gettimeofday.cpp +++ b/libc/src/time/linux/gettimeofday.cpp @@ -11,6 +11,7 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" #include "src/errno/libc_errno.h" +#include "src/time/linux/clockGetTimeImpl.h" #include // For syscall numbers. @@ -21,26 +22,19 @@ LLVM_LIBC_FUNCTION(int, gettimeofday, (struct timeval * tv, [[maybe_unused]] void *unused)) { if (tv == nullptr) return 0; - struct timespec tp; -#if SYS_clock_gettime - int ret = __llvm_libc::syscall_impl(SYS_clock_gettime, - static_cast(CLOCK_REALTIME), - reinterpret_cast(&tp)); -#elif defined(SYS_clock_gettime64) - int ret = __llvm_libc::syscall_impl(SYS_clock_gettime64, - static_cast(CLOCK_REALTIME), - reinterpret_cast(&tp)); -#else -#error "SYS_clock_gettime and SYS_clock_gettime64 syscalls not available." -#endif + + struct timespec ts; + auto result = internal::clock_gettimeimpl(CLOCK_REALTIME, &ts); + // A negative return value indicates an error with the magnitude of the // value being the error code. - if (ret < 0) { - libc_errno = -ret; + if (!result.has_value()) { + libc_errno = result.error(); return -1; } - tv->tv_sec = tp.tv_sec; - tv->tv_usec = static_cast(tp.tv_nsec / 1000); + + tv->tv_sec = ts.tv_sec; + tv->tv_usec = static_cast(ts.tv_nsec / 1000); return 0; } diff --git a/libc/src/time/linux/time.cpp b/libc/src/time/linux/time.cpp index 34cca42adf5ba..4dbcabc896351 100644 --- a/libc/src/time/linux/time.cpp +++ b/libc/src/time/linux/time.cpp @@ -11,6 +11,7 @@ #include "src/__support/OSUtil/syscall.h" // For internal syscall function. #include "src/__support/common.h" #include "src/errno/libc_errno.h" +#include "src/time/linux/clockGetTimeImpl.h" #include // For syscall numbers. #include @@ -20,17 +21,9 @@ namespace __llvm_libc { LLVM_LIBC_FUNCTION(time_t, time, (time_t * tp)) { // TODO: Use the Linux VDSO to fetch the time and avoid the syscall. struct timespec ts; -#if SYS_clock_gettime - int ret = __llvm_libc::syscall_impl(SYS_clock_gettime, CLOCK_REALTIME, - reinterpret_cast(&ts)); -#elif defined(SYS_clock_gettime64) - int ret = __llvm_libc::syscall_impl(SYS_clock_gettime64, CLOCK_REALTIME, - reinterpret_cast(&ts)); -#else -#error "SYS_clock_gettime and SYS_clock_gettime64 syscalls not available." -#endif - if (ret < 0) { - libc_errno = -ret; + auto result = internal::clock_gettimeimpl(CLOCK_REALTIME, &ts); + if (!result.has_value()) { + libc_errno = result.error(); return -1; }