[libc-commits] [libc] [libc] move abs_timesout and monotonicity out of linux dir (PR #167719)

via libc-commits libc-commits at lists.llvm.org
Fri Nov 28 06:19:11 PST 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libc

Author: Shreeyash Pandey (bojle)

<details>
<summary>Changes</summary>

This patch moves abs_timeout and monotonicity out of the linux dir into common. Both of these functions depend on clock_gettime which is the actual os-dependent component. As other features in `__support/threads` may want to use these, it's better to share it in common.


---

Patch is 29.92 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/167719.diff


34 Files Affected:

- (modified) libc/hdr/errno_macros.h (+3-1) 
- (modified) libc/include/errno.h.def (+7-1) 
- (added) libc/include/llvm-libc-macros/darwin/CMakeLists.txt (+5) 
- (added) libc/include/llvm-libc-macros/darwin/time-macros.h (+14) 
- (modified) libc/include/llvm-libc-macros/time-macros.h (+2) 
- (modified) libc/include/llvm-libc-types/clockid_t.h (+6) 
- (modified) libc/include/llvm-libc-types/struct_timespec.h (+6) 
- (modified) libc/include/llvm-libc-types/struct_timeval.h (+6) 
- (modified) libc/include/llvm-libc-types/suseconds_t.h (+6) 
- (modified) libc/include/llvm-libc-types/time_t_32.h (+6) 
- (modified) libc/include/llvm-libc-types/time_t_64.h (+6) 
- (modified) libc/src/__support/OSUtil/darwin/exit.cpp (+1-2) 
- (added) libc/src/__support/threads/darwin/CMakeLists.txt (+11) 
- (added) libc/src/__support/threads/darwin/mutex.h (+132) 
- (modified) libc/src/__support/threads/linux/futex_utils.h (+1-1) 
- (modified) libc/src/__support/threads/linux/raw_mutex.h (+1-1) 
- (modified) libc/src/__support/threads/linux/rwlock.h (+1-1) 
- (modified) libc/src/__support/threads/mutex.h (+3-1) 
- (modified) libc/src/__support/time/CMakeLists.txt (+29) 
- (renamed) libc/src/__support/time/abs_timeout.h (+5-5) 
- (renamed) libc/src/__support/time/clock_conversion.h (+24-2) 
- (added) libc/src/__support/time/darwin/CMakeLists.txt (+12) 
- (added) libc/src/__support/time/darwin/clock_gettime.cpp (+42) 
- (modified) libc/src/__support/time/linux/CMakeLists.txt (-29) 
- (renamed) libc/src/__support/time/monotonicity.h (+7-7) 
- (modified) libc/src/pthread/pthread_rwlock_clockwrlock.cpp (+1-1) 
- (modified) libc/src/pthread/pthread_rwlock_timedrdlock.cpp (+1-1) 
- (modified) libc/src/pthread/pthread_rwlock_timedwrlock.cpp (+1-1) 
- (added) libc/src/time/darwin/CMakeLists.txt (+10) 
- (added) libc/src/time/darwin/clock_gettime.cpp (+28) 
- (added) libc/test/src/__support/threads/darwin/CMakeLists.txt (+11) 
- (added) libc/test/src/__support/threads/darwin/mutex_test.cpp (+25) 
- (added) libc/test/src/__support/time/darwin/CMakeLists.txt (+8) 
- (added) libc/test/src/__support/time/darwin/clock_gettime.cpp (+20) 


``````````diff
diff --git a/libc/hdr/errno_macros.h b/libc/hdr/errno_macros.h
index 27ea49977d8c8..ce3453d16bce1 100644
--- a/libc/hdr/errno_macros.h
+++ b/libc/hdr/errno_macros.h
@@ -15,7 +15,9 @@
 #include <linux/errno.h>
 
 #include "include/llvm-libc-macros/error-number-macros.h"
-#else // __linux__
+#elif __APPLE__
+#include <sys/errno.h>
+#else // __APPLE__
 #include "include/llvm-libc-macros/generic-error-number-macros.h"
 #endif
 
diff --git a/libc/include/errno.h.def b/libc/include/errno.h.def
index aa1f6c9e48444..ba9864439369a 100644
--- a/libc/include/errno.h.def
+++ b/libc/include/errno.h.def
@@ -21,8 +21,14 @@
 
 #include "llvm-libc-macros/linux/error-number-macros.h"
 
-#else // __linux__
+#elif __APPLE__
+
+#include <sys/errno.h>
+
+#else // __APPLE__
+
 #include "llvm-libc-macros/generic-error-number-macros.h"
+
 #endif
 
 __BEGIN_C_DECLS
diff --git a/libc/include/llvm-libc-macros/darwin/CMakeLists.txt b/libc/include/llvm-libc-macros/darwin/CMakeLists.txt
new file mode 100644
index 0000000000000..ea08c63c00301
--- /dev/null
+++ b/libc/include/llvm-libc-macros/darwin/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_header(
+  time_macros
+  HDR
+    time-macros.h
+)
diff --git a/libc/include/llvm-libc-macros/darwin/time-macros.h b/libc/include/llvm-libc-macros/darwin/time-macros.h
new file mode 100644
index 0000000000000..477dfa8eda85f
--- /dev/null
+++ b/libc/include/llvm-libc-macros/darwin/time-macros.h
@@ -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
diff --git a/libc/include/llvm-libc-macros/time-macros.h b/libc/include/llvm-libc-macros/time-macros.h
index 30e0a310a5485..c026df29b1e7f 100644
--- a/libc/include/llvm-libc-macros/time-macros.h
+++ b/libc/include/llvm-libc-macros/time-macros.h
@@ -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
diff --git a/libc/include/llvm-libc-types/clockid_t.h b/libc/include/llvm-libc-types/clockid_t.h
index 4b059599502c4..926948717c664 100644
--- a/libc/include/llvm-libc-types/clockid_t.h
+++ b/libc/include/llvm-libc-types/clockid_t.h
@@ -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
diff --git a/libc/include/llvm-libc-types/struct_timespec.h b/libc/include/llvm-libc-types/struct_timespec.h
index 28b5a571f6790..8993ecc7db8f0 100644
--- a/libc/include/llvm-libc-types/struct_timespec.h
+++ b/libc/include/llvm-libc-types/struct_timespec.h
@@ -9,6 +9,11 @@
 #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 {
@@ -16,5 +21,6 @@ struct timespec {
   /* TODO: BIG_ENDIAN may require padding. */
   long tv_nsec; /* Nanoseconds.  */
 };
+#endif // __APPLE__
 
 #endif // LLVM_LIBC_TYPES_STRUCT_TIMESPEC_H
diff --git a/libc/include/llvm-libc-types/struct_timeval.h b/libc/include/llvm-libc-types/struct_timeval.h
index 9595d85a46c8f..41f0b4e92932e 100644
--- a/libc/include/llvm-libc-types/struct_timeval.h
+++ b/libc/include/llvm-libc-types/struct_timeval.h
@@ -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
diff --git a/libc/include/llvm-libc-types/suseconds_t.h b/libc/include/llvm-libc-types/suseconds_t.h
index 8e926e8401f5c..acc1822cb59e1 100644
--- a/libc/include/llvm-libc-types/suseconds_t.h
+++ b/libc/include/llvm-libc-types/suseconds_t.h
@@ -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
diff --git a/libc/include/llvm-libc-types/time_t_32.h b/libc/include/llvm-libc-types/time_t_32.h
index 2c415f6fa9dca..8d7a81e5ce7f7 100644
--- a/libc/include/llvm-libc-types/time_t_32.h
+++ b/libc/include/llvm-libc-types/time_t_32.h
@@ -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
diff --git a/libc/include/llvm-libc-types/time_t_64.h b/libc/include/llvm-libc-types/time_t_64.h
index 8f7fd3233646e..c8267abe31289 100644
--- a/libc/include/llvm-libc-types/time_t_64.h
+++ b/libc/include/llvm-libc-types/time_t_64.h
@@ -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
diff --git a/libc/src/__support/OSUtil/darwin/exit.cpp b/libc/src/__support/OSUtil/darwin/exit.cpp
index 7439db2ef38b0..a5fa4a7522189 100644
--- a/libc/src/__support/OSUtil/darwin/exit.cpp
+++ b/libc/src/__support/OSUtil/darwin/exit.cpp
@@ -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
diff --git a/libc/src/__support/threads/darwin/CMakeLists.txt b/libc/src/__support/threads/darwin/CMakeLists.txt
new file mode 100644
index 0000000000000..2a7ce0676f68f
--- /dev/null
+++ b/libc/src/__support/threads/darwin/CMakeLists.txt
@@ -0,0 +1,11 @@
+if(NOT TARGET libc.src.__support.OSUtil.osutil)
+  return()
+endif()
+
+add_header_library(
+  mutex
+  HDRS
+    mutex.h
+  DEPENDS
+    libc.src.__support.threads.mutex_common
+)
diff --git a/libc/src/__support/threads/darwin/mutex.h b/libc/src/__support/threads/darwin/mutex.h
new file mode 100644
index 0000000000000..1ad09ba1cdf49
--- /dev/null
+++ b/libc/src/__support/threads/darwin/mutex.h
@@ -0,0 +1,132 @@
+//===--- Implementation of a Darwin mutex class ------------------*- C++
+//-*-===//
+//
+// 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_SRC___SUPPORT_THREADS_DARWIN_MUTEX_H
+#define LLVM_LIBC_SRC___SUPPORT_THREADS_DARWIN_MUTEX_H
+
+#include "src/__support/libc_assert.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/threads/mutex_common.h"
+#include "src/__support/threads/sleep.h" // For sleep_briefly
+#include "src/__support/time/abs_timeout.h"
+
+#include <mach/mach_init.h> // For mach_thread_self
+#include <mach/mach_port.h> // For mach_port_t and MACH_PORT_NULL
+#include <os/lock.h>        // For os_unfair_lock
+#include <time.h>           // For clock_gettime
+
+namespace LIBC_NAMESPACE_DECL {
+
+// This file is an implementation of `LIBC_NAMESPACE::mutex` for Darwin-based
+// platforms. It is a wrapper around `os_unfair_lock`, which is a low-level,
+// high-performance locking primitive provided by the kernel.
+//
+// `os_unfair_lock` is a non-recursive, thread-owned lock that blocks waiters
+// efficiently in the kernel. As the name implies, it is "unfair," meaning
+// it does not guarantee the order in which waiting threads acquire the lock.
+// This trade-off allows for higher performance in contended scenarios.
+//
+// The lock must be unlocked from the same thread that locked it. Attempting
+// to unlock from a different thread will result in a runtime error.
+//
+// This implementation is suitable for simple critical sections where fairness
+// and reentrancy are not concerns.
+
+class Mutex final {
+  os_unfair_lock_s lock_val = OS_UNFAIR_LOCK_INIT;
+  mach_port_t owner = MACH_PORT_NULL;
+
+  // API compatibility fields.
+  unsigned char timed;
+  unsigned char recursive;
+  unsigned char robust;
+  unsigned char pshared;
+
+public:
+  LIBC_INLINE constexpr Mutex(bool is_timed, bool is_recursive, bool is_robust,
+                              bool is_pshared)
+      : owner(MACH_PORT_NULL), timed(is_timed), recursive(is_recursive),
+        robust(is_robust), pshared(is_pshared) {}
+
+  LIBC_INLINE constexpr Mutex()
+      : owner(MACH_PORT_NULL), timed(0), recursive(0), robust(0), pshared(0) {}
+
+  LIBC_INLINE static MutexError init(Mutex *mutex, bool is_timed, bool is_recur,
+                                     bool is_robust, bool is_pshared) {
+    mutex->lock_val = OS_UNFAIR_LOCK_INIT;
+    mutex->owner = MACH_PORT_NULL;
+    mutex->timed = is_timed;
+    mutex->recursive = is_recur;
+    mutex->robust = is_robust;
+    mutex->pshared = is_pshared;
+    return MutexError::NONE;
+  }
+
+  LIBC_INLINE static MutexError destroy(Mutex *lock) {
+    LIBC_ASSERT(lock->owner == MACH_PORT_NULL &&
+                "Mutex destroyed while locked.");
+    return MutexError::NONE;
+  }
+
+  LIBC_INLINE MutexError lock() {
+    os_unfair_lock_lock(&lock_val);
+    owner = mach_thread_self();
+    return MutexError::NONE;
+  }
+
+  LIBC_INLINE MutexError timed_lock(internal::AbsTimeout abs_time) {
+    while (true) {
+      if (try_lock() == MutexError::NONE) {
+        return MutexError::NONE;
+      }
+
+      // Manually check if the timeout has expired.
+      struct timespec now;
+      // The clock used here must match the clock used to create the
+      // absolute timeout.
+      clock_gettime(abs_time.is_realtime() ? CLOCK_REALTIME : CLOCK_MONOTONIC,
+                    &now);
+      const timespec &target_ts = abs_time.get_timespec();
+
+      if (now.tv_sec > target_ts.tv_sec || (now.tv_sec == target_ts.tv_sec &&
+                                            now.tv_nsec >= target_ts.tv_nsec)) {
+        // We might have acquired the lock between the last try_lock() and now.
+        // To avoid returning TIMEOUT incorrectly, we do one last try_lock().
+        if (try_lock() == MutexError::NONE)
+          return MutexError::NONE;
+        return MutexError::TIMEOUT;
+      }
+
+      sleep_briefly();
+    }
+  }
+
+  LIBC_INLINE MutexError unlock() {
+    // This check is crucial. It prevents both double-unlocks and unlocks
+    // by threads that do not own the mutex.
+    if (owner != mach_thread_self()) {
+      return MutexError::UNLOCK_WITHOUT_LOCK;
+    }
+    owner = MACH_PORT_NULL;
+    os_unfair_lock_unlock(&lock_val);
+    return MutexError::NONE;
+  }
+
+  LIBC_INLINE MutexError try_lock() {
+    if (os_unfair_lock_trylock(&lock_val)) {
+      owner = mach_thread_self();
+      return MutexError::NONE;
+    }
+    return MutexError::BUSY;
+  }
+};
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_DARWIN_MUTEX_H
diff --git a/libc/src/__support/threads/linux/futex_utils.h b/libc/src/__support/threads/linux/futex_utils.h
index 943a99ab38c8c..e1cfa36566555 100644
--- a/libc/src/__support/threads/linux/futex_utils.h
+++ b/libc/src/__support/threads/linux/futex_utils.h
@@ -16,7 +16,7 @@
 #include "src/__support/macros/attributes.h"
 #include "src/__support/macros/config.h"
 #include "src/__support/threads/linux/futex_word.h"
-#include "src/__support/time/linux/abs_timeout.h"
+#include "src/__support/time/abs_timeout.h"
 #include <linux/errno.h>
 #include <linux/futex.h>
 
diff --git a/libc/src/__support/threads/linux/raw_mutex.h b/libc/src/__support/threads/linux/raw_mutex.h
index 47f0aa70f1c46..8f69da2ceab07 100644
--- a/libc/src/__support/threads/linux/raw_mutex.h
+++ b/libc/src/__support/threads/linux/raw_mutex.h
@@ -17,7 +17,7 @@
 #include "src/__support/threads/linux/futex_utils.h"
 #include "src/__support/threads/linux/futex_word.h"
 #include "src/__support/threads/sleep.h"
-#include "src/__support/time/linux/abs_timeout.h"
+#include "src/__support/time/abs_timeout.h"
 
 #ifndef LIBC_COPT_TIMEOUT_ENSURE_MONOTONICITY
 #define LIBC_COPT_TIMEOUT_ENSURE_MONOTONICITY 1
diff --git a/libc/src/__support/threads/linux/rwlock.h b/libc/src/__support/threads/linux/rwlock.h
index f7aeb5b709aa3..165e17239bbd5 100644
--- a/libc/src/__support/threads/linux/rwlock.h
+++ b/libc/src/__support/threads/linux/rwlock.h
@@ -35,7 +35,7 @@
 #endif
 
 #if LIBC_COPT_TIMEOUT_ENSURE_MONOTONICITY
-#include "src/__support/time/linux/monotonicity.h"
+#include "src/__support/time/monotonicity.h"
 #endif
 
 namespace LIBC_NAMESPACE_DECL {
diff --git a/libc/src/__support/threads/mutex.h b/libc/src/__support/threads/mutex.h
index f64f7e7b40082..e2401507d86ac 100644
--- a/libc/src/__support/threads/mutex.h
+++ b/libc/src/__support/threads/mutex.h
@@ -42,7 +42,9 @@
 
 #if defined(__linux__)
 #include "src/__support/threads/linux/mutex.h"
-#endif // __linux__
+#elif defined(__APPLE__)
+#include "src/__support/threads/darwin/mutex.h"
+#endif
 
 #elif LIBC_THREAD_MODE == LIBC_THREAD_MODE_SINGLE
 
diff --git a/libc/src/__support/time/CMakeLists.txt b/libc/src/__support/time/CMakeLists.txt
index 3851037e4161f..b90f977b00fe5 100644
--- a/libc/src/__support/time/CMakeLists.txt
+++ b/libc/src/__support/time/CMakeLists.txt
@@ -28,3 +28,32 @@ if(TARGET libc.src.__support.time.${LIBC_TARGET_OS}.clock_settime)
       libc.src.__support.time.${LIBC_TARGET_OS}.clock_settime
   )
 endif()
+
+add_header_library(
+  abs_timeout
+  HDRS
+    abs_timeout.h
+  DEPENDS
+    libc.hdr.types.struct_timespec
+    libc.src.__support.time.units
+    libc.src.__support.CPP.expected
+)
+
+add_header_library(
+  clock_conversion
+  HDRS
+    clock_conversion.h
+  DEPENDS
+    .clock_gettime
+    libc.src.__support.time.units
+)
+
+add_header_library(
+  monotonicity
+  HDRS
+    monotonicity.h
+  DEPENDS
+    .clock_conversion
+    .abs_timeout
+    libc.hdr.time_macros
+)
diff --git a/libc/src/__support/time/linux/abs_timeout.h b/libc/src/__support/time/abs_timeout.h
similarity index 85%
rename from libc/src/__support/time/linux/abs_timeout.h
rename to libc/src/__support/time/abs_timeout.h
index 37e602672208f..23ad52f530545 100644
--- a/libc/src/__support/time/linux/abs_timeout.h
+++ b/libc/src/__support/time/abs_timeout.h
@@ -1,13 +1,13 @@
-//===--- Linux absolute timeout ---------------------------------*- C++ -*-===//
+//===--- absolute timeout ---------------------------------*- C++ -*-===//
 //
 // 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_SRC___SUPPORT_TIME_LINUX_ABS_TIMEOUT_H
-#define LLVM_LIBC_SRC___SUPPORT_TIME_LINUX_ABS_TIMEOUT_H
+#ifndef LLVM_LIBC_SRC___SUPPORT_TIME_ABS_TIMEOUT_H
+#define LLVM_LIBC_SRC___SUPPORT_TIME_ABS_TIMEOUT_H
 
 #include "hdr/time_macros.h"
 #include "hdr/types/struct_timespec.h"
@@ -47,4 +47,4 @@ class AbsTimeout {
 } // namespace internal
 } // namespace LIBC_NAMESPACE_DECL
 
-#endif // LLVM_LIBC_SRC___SUPPORT_TIME_LINUX_ABS_TIMEOUT_H
+#endif // LLVM_LIBC_SRC___SUPPORT_TIME_ABS_TIMEOUT_H
diff --git a/libc/src/__support/time/linux/clock_conversion.h b/libc/src/__support/time/clock_conversion.h
similarity index 54%
rename from libc/src/__support/time/linux/clock_conversion.h
rename to libc/src/__support/time/clock_conversion.h
index ac5357d308d7c..acf0b21516467 100644
--- a/libc/src/__support/time/linux/clock_conversion.h
+++ b/libc/src/__support/time/clock_conversion.h
@@ -1,10 +1,10 @@
-//===--- clock conversion linux implementation ------------------*- C++ -*-===//
+//===--- clock conversion implementation ------------------*- C++ -*-===//
 //
 // 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_SRC___SUPPORT_TIME_LINUX_CLOCK_CONVERSION_H
 #define LLVM_LIBC_SRC___SUPPORT_TIME_LINUX_CLOCK_CONVERSION_H
@@ -16,6 +16,28 @@
 namespace LIBC_NAMESPACE_DECL {
 namespace internal {
 
+/**
+ * @brief Convert a timespec value from one clock domain to another.
+ *
+ * The function takes a timestamp that is expressed in terms of the clock
+ * identified by param from and returns an equivalent timestamp expressed
+ * in terms of the clock identified by param to.
+ *
+ * Internally it obtains the current time of both clocks with
+ * clock_gettime, then subtracts the source clock’s value and
+ * adds the target clock’s value. The result is normalised so that
+ * the nanoseconds field is always in the range [0, 1 s).
+ *
+ * This is useful, for example, for converting a value obtained from
+ * CLOCK_MONOTONIC to CLOCK_REALTIME (or vice‑versa) so that the
+ * timestamp can be displayed to a user or stored in a format that
+ * is independent of the original clock domain.
+ *
+ * @param input The timestamp to convert
+ * @param from Clock ID of the original timestamp (e.g. CLOCK_MONOTONIC).
+ * @param to Clock ID of the desired timestamp (e.g. CLOCK_REALTIME).
+ * @return The converted timespec
+ */
 LIBC_INLINE timespec convert_clock(timespec input, clockid_t from,
                                    clockid_t to) {
   using namespace time_units;
diff --git a/libc/src/__support/time/darwin/CMakeLists.txt b/libc/src/__support/time/darwin/CMakeLists.txt
new file mode 100644
index 0000000000000..a06a41289a41c
--- /dev/null
+++ b/libc/src/__support/time/darwin/CMakeLists.txt
@@ -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
+)
diff --git a/libc/src/__support/time/darwin/clock_gettime.cpp b/libc/src/__support/time/darwin/clock_gettime.cpp
new file mode 100644
index 0000000000000..aa483aa9a01d2
--- /dev/null
+++ b/libc/src/__support/time/darwin/clock_gettime.cpp
@@ -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"...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/167719


More information about the libc-commits mailing list