Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions libc/include/llvm-libc-macros/darwin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
add_header(
time_macros
HDR
time-macros.h
)
14 changes: 14 additions & 0 deletions libc/include/llvm-libc-macros/darwin/time-macros.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//===-- Definition of macros from time.h ---------------------------------===//
//
// 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_MACROS_LINUX_TIME_MACROS_H
#define LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H

#include <_time.h>

#endif // LLVM_LIBC_MACROS_LINUX_TIME_MACROS_H
2 changes: 2 additions & 0 deletions libc/include/llvm-libc-macros/time-macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include "linux/time-macros.h"
#elif defined(__ELF__)
#include "baremetal/time-macros.h"
#elif defined(__APPLE__)
#include "darwin/time-macros.h"
#else
#define CLOCKS_PER_SEC 1000000
#endif
Expand Down
6 changes: 6 additions & 0 deletions libc/include/llvm-libc-types/clockid_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
#ifndef LLVM_LIBC_TYPES_CLOCKID_T_H
#define LLVM_LIBC_TYPES_CLOCKID_T_H

#if defined(__APPLE__)
// Darwin provides its own defintion for clockid_t . Use that to prevent
// redeclaration errors and correctness.
#include <_time.h>
#else
typedef int clockid_t;
#endif // __APPLE__

#endif // LLVM_LIBC_TYPES_CLOCKID_T_H
6 changes: 6 additions & 0 deletions libc/include/llvm-libc-types/struct_timespec.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,18 @@
#ifndef LLVM_LIBC_TYPES_STRUCT_TIMESPEC_H
#define LLVM_LIBC_TYPES_STRUCT_TIMESPEC_H

#if defined(__APPLE__)
// Darwin provides its own definition for struct timespec. Include it directly
// to ensure type compatibility and avoid redefinition errors.
#include <sys/_types/_timespec.h>
#else
#include "time_t.h"

struct timespec {
time_t tv_sec; /* Seconds. */
/* TODO: BIG_ENDIAN may require padding. */
long tv_nsec; /* Nanoseconds. */
};
#endif // __APPLE__

#endif // LLVM_LIBC_TYPES_STRUCT_TIMESPEC_H
6 changes: 6 additions & 0 deletions libc/include/llvm-libc-types/struct_timeval.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,15 @@
#include "suseconds_t.h"
#include "time_t.h"

#if defined(__APPLE__)
// Darwin provides its own definition for struct timeval. Include it directly
// to ensure type compatibility and avoid redefinition errors.
#include <sys/_types/_timeval.h>
#else
struct timeval {
time_t tv_sec; // Seconds
suseconds_t tv_usec; // Micro seconds
};
#endif // __APPLE__

#endif // LLVM_LIBC_TYPES_STRUCT_TIMEVAL_H
6 changes: 6 additions & 0 deletions libc/include/llvm-libc-types/suseconds_t.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
// types...] and suseconds_t are no greater than the width of type long.

// The kernel expects 64 bit suseconds_t at least on x86_64.
#if defined(__APPLE__)
// Darwin provides its own definition for suseconds_t. Include it directly
// to ensure type compatibility and avoid redefinition errors.
#include <sys/_types/_suseconds_t.h>
#else
typedef long suseconds_t;
#endif // __APPLE__

#endif // LLVM_LIBC_TYPES_SUSECONDS_T_H
6 changes: 6 additions & 0 deletions libc/include/llvm-libc-types/time_t_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
#ifndef LLVM_LIBC_TYPES_TIME_T_32_H
#define LLVM_LIBC_TYPES_TIME_T_32_H

#if defined(__APPLE__)
// Darwin provides its own definition for time_t. Include it directly
// to ensure type compatibility and avoid redefinition errors.
#include <sys/_types/_time_t.h>
#else
typedef __INT32_TYPE__ time_t;
#endif // __APPLE__

#endif // LLVM_LIBC_TYPES_TIME_T_32_H
6 changes: 6 additions & 0 deletions libc/include/llvm-libc-types/time_t_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@
#ifndef LLVM_LIBC_TYPES_TIME_T_64_H
#define LLVM_LIBC_TYPES_TIME_T_64_H

#if defined(__APPLE__)
// Darwin provides its own definition for time_t. Include it directly
// to ensure type compatibility and avoid redefinition errors.
#include <sys/_types/_time_t.h>
#else
typedef __INT64_TYPE__ time_t;
#endif // __APPLE__

#endif // LLVM_LIBC_TYPES_TIME_T_64_H
3 changes: 1 addition & 2 deletions libc/src/__support/OSUtil/darwin/exit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ namespace LIBC_NAMESPACE_DECL {
namespace internal {

[[noreturn]] void exit(int status) {
for (;;) {
for (;;)
LIBC_NAMESPACE::syscall_impl<long>(SYS_exit, status);
}
}

} // namespace internal
Expand Down
12 changes: 12 additions & 0 deletions libc/src/__support/time/darwin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
add_object_library(
clock_gettime
SRCS
clock_gettime.cpp
HDRS
../clock_gettime.h
DEPENDS
libc.src.__support.common
libc.src.__support.error_or
libc.hdr.types.struct_timeval
libc.hdr.types.struct_timespec
)
42 changes: 42 additions & 0 deletions libc/src/__support/time/darwin/clock_gettime.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//===-- Darwin implementation of internal clock_gettime -------------------===//
//
// 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/__support/time/clock_gettime.h"
#include "hdr/errno_macros.h" // For EINVAL
#include "hdr/time_macros.h"
#include "hdr/types/struct_timespec.h"
#include "hdr/types/struct_timeval.h"
#include "src/__support/OSUtil/syscall.h" // For syscall_impl
#include "src/__support/common.h"
#include "src/__support/error_or.h"
#include <sys/syscall.h> // For SYS_gettimeofday
#include <sys/time.h> // For struct timezone

namespace LIBC_NAMESPACE_DECL {
namespace internal {

ErrorOr<int> clock_gettime(clockid_t clockid, struct timespec *ts) {
if (clockid != CLOCK_REALTIME)
return Error(EINVAL);
struct timeval tv;
// The second argument to gettimeofday is a timezone pointer
// The third argument is mach_absolute_time
// Both of these, we don't need here, so they are 0
long ret = LIBC_NAMESPACE::syscall_impl<long>(
SYS_gettimeofday, reinterpret_cast<long>(&tv), 0, 0);
if (ret != 0)
// The syscall returns -1 on error and sets errno.
return Error(EINVAL);

ts->tv_sec = tv.tv_sec;
ts->tv_nsec = tv.tv_usec * 1000;
return 0;
}

} // namespace internal
} // namespace LIBC_NAMESPACE_DECL
10 changes: 10 additions & 0 deletions libc/src/time/darwin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
add_entrypoint_object(
clock_gettime
SRCS
clock_gettime.cpp
HDRS
# The public header is part of the parent directory's library.
DEPENDS
libc.src.__support.time.clock_gettime
libc.src.errno.errno
)
28 changes: 28 additions & 0 deletions libc/src/time/darwin/clock_gettime.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//===---- Darwin 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/common.h"
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
#include "src/__support/time/clock_gettime.h"

namespace LIBC_NAMESPACE_DECL {

LLVM_LIBC_FUNCTION(int, clock_gettime,
(clockid_t clockid, struct timespec *ts)) {
auto result = internal::clock_gettime(clockid, ts);
if (!result.has_value()) {
libc_errno = result.error();
return -1;
}
return 0;
}

} // namespace LIBC_NAMESPACE_DECL
8 changes: 8 additions & 0 deletions libc/test/src/__support/time/darwin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
add_libc_test(
clock_gettime
SUITE libc-support-time-tests
SRCS clock_gettime.cpp
DEPENDS
libc.src.__support.CPP.expected
libc.src.__support.time.darwin.clock_gettime
)
20 changes: 20 additions & 0 deletions libc/test/src/__support/time/darwin/clock_gettime.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===-- unit tests for darwin's time utilities --------------------------===//
//
// 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/__support/time/clock_gettime.h"
#include "src/__support/CPP/expected.h"
#include "test/UnitTest/Test.h"

template <class T, class E>
using expected = LIBC_NAMESPACE::cpp::expected<T, E>;

TEST(LlvmLibcSupportDarwinClockGetTime, BasicGetTime) {
struct timespec ts;
auto result = LIBC_NAMESPACE::internal::clock_gettime(CLOCK_REALTIME, &ts);
ASSERT_TRUE(result.has_value());
}
Loading