diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td --- a/libc/config/linux/api.td +++ b/libc/config/linux/api.td @@ -96,8 +96,10 @@ let Types = [ "clock_t", "time_t", + "time64_t", "struct tm", "struct timespec", + "struct timespec64", "struct timeval", "clockid_t", ]; @@ -112,6 +114,8 @@ // Needed according to posix standard "time_t", "struct timespec", + "time64_t", + "struct timespec64", ]; } @@ -201,7 +205,7 @@ def SysSelectAPI : PublicAPI<"sys/select.h"> { let Types = ["fd_set", "sigset_t", "suseconds_t", "time_t", "struct timespec", - "struct timeval"]; + "time64_t", "struct timespec64", "struct timeval"]; } def SysSocketAPI : PublicAPI<"sys/socket.h"> { @@ -214,8 +218,8 @@ def SysStatAPI : PublicAPI<"sys/stat.h"> { let Types = ["mode_t", "dev_t", "ino_t", "nlink_t", "uid_t", "gid_t", "off_t", - "struct timespec", "struct timeval", "blksize_t", "blkcnt_t", - "struct stat"]; + "struct timespec", "struct timespec64", "struct timeval", "blksize_t", + "blkcnt_t", "struct stat"]; } def SysWaitAPI : PublicAPI<"sys/wait.h"> { @@ -230,7 +234,7 @@ let Types = ["blkcnt_t", "blksize_t", "clockid_t", "dev_t", "gid_t", "ino_t", "mode_t", "nlink_t", "off_t", "pid_t", "pthread_attr_t", "pthread_key_t", "pthread_mutex_t", "pthread_mutexattr_t", "pthread_once_t", "pthread_t", - "size_t", "ssize_t", "suseconds_t", "time_t", "uid_t"]; + "size_t", "ssize_t", "suseconds_t", "time_t", "time64_t", "uid_t"]; } def SysUtsNameAPI : PublicAPI<"sys/utsname.h"> { diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -133,8 +133,10 @@ .llvm-libc-macros.time_macros .llvm-libc-types.clock_t .llvm-libc-types.time_t + .llvm-libc-types.time64_t .llvm-libc-types.struct_tm .llvm-libc-types.struct_timespec + .llvm-libc-types.struct_timespec64 .llvm-libc-types.struct_timeval .llvm-libc-types.clockid_t ) @@ -263,6 +265,8 @@ # Needed according to posix standard .llvm-libc-types.time_t .llvm-libc-types.struct_timespec + .llvm-libc-types.time64_t + .llvm-libc-types.struct_timespec64 ) add_gen_header( @@ -359,6 +363,7 @@ .llvm-libc-types.gid_t .llvm-libc-types.off_t .llvm-libc-types.struct_timespec + .llvm-libc-types.struct_timespec64 .llvm-libc-types.struct_timeval .llvm-libc-types.blksize_t .llvm-libc-types.blkcnt_t @@ -377,6 +382,8 @@ .llvm-libc-types.suseconds_t .llvm-libc-types.time_t .llvm-libc-types.struct_timespec + .llvm-libc-types.time64_t + .llvm-libc-types.struct_timespec64 .llvm-libc-types.struct_timeval ) @@ -448,6 +455,7 @@ .llvm-libc-types.ssize_t .llvm-libc-types.suseconds_t .llvm-libc-types.time_t + .llvm-libc-types.time64_t .llvm-libc-types.uid_t ) diff --git a/libc/include/llvm-libc-types/CMakeLists.txt b/libc/include/llvm-libc-types/CMakeLists.txt --- a/libc/include/llvm-libc-types/CMakeLists.txt +++ b/libc/include/llvm-libc-types/CMakeLists.txt @@ -56,6 +56,7 @@ add_header(rlim_t HDR rlim_t.h) add_header(rlim64_t HDR rlim64_t.h) add_header(time_t HDR time_t.h) +add_header(time64_t HDR time64_t.h) add_header(stack_t HDR stack_t.h) add_header(suseconds_t HDR suseconds_t.h) add_header(struct_timeval HDR struct_timeval.h DEPENDS .suseconds_t .time_t) @@ -70,12 +71,13 @@ add_header(sigset_t HDR sigset_t.h DEPENDS libc.include.llvm-libc-macros.signal_macros) add_header(struct_sigaction HDR struct_sigaction.h DEPENDS .sigset_t .siginfo_t) add_header(struct_timespec HDR struct_timespec.h DEPENDS .time_t) +add_header(struct_timespec64 HDR struct_timespec64.h DEPENDS .time64_t) add_header( struct_stat HDR struct_stat.h DEPENDS .dev_t .ino_t .mode_t .nlink_t .uid_t .gid_t .off_t .struct_timespec - .blksize_t .blkcnt_t + .struct_timespec64 .blksize_t .blkcnt_t ) add_header(struct_tm HDR struct_tm.h) add_header(struct_utsname HDR struct_utsname.h) diff --git a/libc/include/llvm-libc-types/struct_sched_param.h b/libc/include/llvm-libc-types/struct_sched_param.h --- a/libc/include/llvm-libc-types/struct_sched_param.h +++ b/libc/include/llvm-libc-types/struct_sched_param.h @@ -11,6 +11,8 @@ #include #include +#include +#include #include struct sched_param { diff --git a/libc/include/llvm-libc-types/struct_stat.h b/libc/include/llvm-libc-types/struct_stat.h --- a/libc/include/llvm-libc-types/struct_stat.h +++ b/libc/include/llvm-libc-types/struct_stat.h @@ -18,6 +18,7 @@ #include #include #include +#include #include struct stat { diff --git a/libc/include/llvm-libc-types/struct_timespec64.h b/libc/include/llvm-libc-types/struct_timespec64.h new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-types/struct_timespec64.h @@ -0,0 +1,20 @@ +//===-- Definition of struct timespec64 -----------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef __LLVM_LIBC_TYPES_TIMESPEC64_H__ +#define __LLVM_LIBC_TYPES_TIMESPEC64_H__ + +#include + +struct timespec64 { + time64_t tv_sec; /* Seconds. */ + /* TODO: BIG_ENDIAN may require padding. */ + long tv_nsec; /* Nanoseconds. */ +}; + +#endif // __LLVM_LIBC_TYPES_TIMESPEC64_H__ diff --git a/libc/include/llvm-libc-types/time64_t.h b/libc/include/llvm-libc-types/time64_t.h new file mode 100644 --- /dev/null +++ b/libc/include/llvm-libc-types/time64_t.h @@ -0,0 +1,14 @@ +//===-- Definition of the type time64_t -----------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef __LLVM_LIBC_TYPES_TIME64_T_H__ +#define __LLVM_LIBC_TYPES_TIME64_T_H__ + +typedef __INT64_TYPE__ time64_t; + +#endif // __LLVM_LIBC_TYPES_TIME64_T_H__ diff --git a/libc/spec/posix.td b/libc/spec/posix.td --- a/libc/spec/posix.td +++ b/libc/spec/posix.td @@ -43,6 +43,7 @@ def ConstStructDirentPtrPtr : ConstType; def StructTimeSpec : NamedType<"struct timespec">; +def StructTimeSpec64 : NamedType<"struct timespec64">; def StructTimeSpecPtr : PtrType; def StructSchedParam : NamedType<"struct sched_param">; @@ -641,7 +642,7 @@ HeaderSpec Sched = HeaderSpec< "sched.h", [], // Macros - [PidT, TimeTType, StructTimeSpec, StructSchedParam], // Types + [PidT, TimeTType, Time64TType, StructTimeSpec, StructTimeSpec64, StructSchedParam], // Types [], // Enumerations [ FunctionSpec< @@ -800,6 +801,7 @@ UidT, GidT, StructTimeSpec, + StructTimeSpec64, StructTimevalType, BlkSizeT, BlkCntT, @@ -1178,7 +1180,7 @@ HeaderSpec Time = HeaderSpec< "time.h", [], // Macros - [ClockIdT, StructTimeSpec, StructTimevalType], // Types + [ClockIdT, StructTimeSpec, StructTimeSpec64, StructTimevalType], // Types [], // Enumerations [ FunctionSpec< @@ -1339,7 +1341,7 @@ HeaderSpec SysSelect = HeaderSpec< "sys/select.h", [], // Macros - [FdSet, SigSetType, StructTimevalType, StructTimeSpec, SuSecondsT, TimeTType], + [FdSet, SigSetType, StructTimevalType, StructTimeSpec, StructTimeSpec64, SuSecondsT, TimeTType, Time64TType], [], // Enumerations [ FunctionSpec< @@ -1386,7 +1388,7 @@ [], // Macros [BlkCntT, BlkSizeT, ClockIdT, DevT, GidT, InoT, ModeTType, NLinkT, OffTType, PidT, PThreadAttrTType, PThreadKeyT, PThreadMutexTType, PThreadMutexAttrTType, PThreadOnceT, PThreadTType, - SizeTType, SSizeTType, SuSecondsT, TimeTType, UidT], + SizeTType, SSizeTType, SuSecondsT, TimeTType, Time64TType, UidT], [], // Enumerations [] // Functions >; diff --git a/libc/spec/spec.td b/libc/spec/spec.td --- a/libc/spec/spec.td +++ b/libc/spec/spec.td @@ -110,6 +110,7 @@ def SigHandlerT : NamedType<"__sighandler_t">; def TimeTType : NamedType<"time_t">; +def Time64TType : NamedType<"time64_t">; def BSearchCompareT : NamedType<"__bsearchcompare_t">; def QSortCompareT : NamedType<"__qsortcompare_t">; diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -1031,6 +1031,7 @@ ClockT, StructTmType, TimeTType, + Time64TType, ], [], // Enumerations [ diff --git a/libc/src/time/linux/nanosleep.cpp b/libc/src/time/linux/nanosleep.cpp --- a/libc/src/time/linux/nanosleep.cpp +++ b/libc/src/time/linux/nanosleep.cpp @@ -21,8 +21,23 @@ #if SYS_nanosleep int ret = __llvm_libc::syscall_impl(SYS_nanosleep, req, rem); #elif defined(SYS_clock_nanosleep_time64) - int ret = - __llvm_libc::syscall_impl(SYS_clock_nanosleep_time64, req, rem); + // SYS_clock_nanosleep_time64 takes a timespec64 struct, which is a struct + // timespec with 64-bit members. In 32-bit systems struct timespec has 32-bit + // members, so we need to fill a timespec64 struct with the 32-bit values + // from struct timespec. + struct timespec64 req64; + req64.tv_sec = req->tv_sec; + req64.tv_nsec = req->tv_nsec; + + struct timespec64 rem64; + rem64.tv_sec = rem->tv_sec; + rem64.tv_nsec = rem->tv_nsec; + + int ret = __llvm_libc::syscall_impl(SYS_clock_nanosleep_time64, + CLOCK_REALTIME, 0, &req64, &rem64); + + rem->tv_sec = static_cast(rem64.tv_sec); + rem->tv_nsec = static_cast(rem64.tv_nsec); #else #error "SYS_nanosleep and SYS_clock_nanosleep_time64 syscalls not available." #endif