Skip to content

Conversation

@bojle
Copy link
Contributor

@bojle bojle commented Nov 12, 2025

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.

@bojle
Copy link
Contributor Author

bojle commented Nov 12, 2025

This is a part of a stack of PRs and my tool is broken without commit-access to this repo. For convenience, please look at the diff of the latest commit 2c04ca1

@bojle
Copy link
Contributor Author

bojle commented Nov 12, 2025

@SchrodingerZhu

@bojle bojle force-pushed the users/bojle/abstimeout branch 4 times, most recently from 27db735 to f8ac650 Compare November 14, 2025 12:15
@github-actions
Copy link

github-actions bot commented Nov 14, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@bojle bojle force-pushed the users/bojle/abstimeout branch from 6780c7f to cfdbe83 Compare November 27, 2025 15:35
@github-actions
Copy link

github-actions bot commented Nov 27, 2025

🐧 Linux x64 Test Results

✅ The build succeeded and no tests ran. This is expected in some build configurations.

@bojle bojle force-pushed the users/bojle/abstimeout branch from cfdbe83 to b8d7e50 Compare November 28, 2025 14:14
@llvmbot llvmbot added the libc label Nov 28, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 28, 2025

@llvm/pr-subscribers-libc

Author: Shreeyash Pandey (bojle)

Changes

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 --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]

@bojle bojle force-pushed the users/bojle/abstimeout branch 2 times, most recently from ee08fa7 to f181323 Compare December 4, 2025 12:48
@bojle
Copy link
Contributor Author

bojle commented Dec 4, 2025

@SchrodingerZhu this patch is ready, can you take a look at it. This would be the last one in the stack before the darwin_mutex patch.

Copy link
Contributor

@SchrodingerZhu SchrodingerZhu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

libc.src.__support.time.linux.abs_timeout

This change generally looks good to me but you may need to update the dependency path for cmake

@bojle
Copy link
Contributor Author

bojle commented Dec 8, 2025

@SchrodingerZhu done

@bojle bojle force-pushed the users/bojle/abstimeout branch from 257547a to 14d7d8f Compare December 8, 2025 13:22
Copy link
Contributor

@SchrodingerZhu SchrodingerZhu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thank you for doing this.

Copy link
Contributor

@SchrodingerZhu SchrodingerZhu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, on another check, I think test dependencies are not updated?

@bojle
Copy link
Contributor Author

bojle commented Dec 8, 2025

ce0643f

they were updated here @SchrodingerZhu

@SchrodingerZhu
Copy link
Contributor

ouch my fault.

@bojle bojle merged commit 2a5420e into llvm:main Dec 8, 2025
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants