[libc-commits] [libc] [llvm] [libc][windows] start time API implementation (PR #117775)

Schrodinger ZHU Yifan via libc-commits libc-commits at lists.llvm.org
Wed Dec 4 07:39:52 PST 2024


================
@@ -0,0 +1,87 @@
+//===--- clock_gettime windows 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/__support/time/clock_gettime.h"
+#include "include/llvm-libc-macros/windows/time-macros-ext.h"
+#include "src/__support/CPP/atomic.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/time/units.h"
+#include <Windows.h>
+
+#ifdef __clang__
+#define UNINITIALIZED [[clang::uninitialized]]
+#else
+#define UNINITIALIZED
+#endif
+
+namespace LIBC_NAMESPACE_DECL {
+namespace internal {
+static long long get_ticks_per_second() {
+  static cpp::Atomic<long long> frequency = 0;
+  auto freq = frequency.load(cpp::MemoryOrder::RELAXED);
+  if (!freq) {
+    UNINITIALIZED LARGE_INTEGER buffer;
+    // On systems that run Windows XP or later, the function will always
+    // succeed and will thus never return zero.
+    ::QueryPerformanceFrequency(&buffer);
+    frequency.store(buffer.QuadPart, cpp::MemoryOrder::RELAXED);
+    return buffer.QuadPart;
+  }
+  return freq;
+}
+
+ErrorOr<int> clock_gettime(clockid_t clockid, timespec *ts) {
+  using namespace time_units;
+  ErrorOr<int> ret = 0;
+  switch (clockid) {
+  default:
+    ret = cpp::unexpected(EINVAL);
+    break;
+
+  case CLOCK_MONOTONIC: {
+    // see
+    // https://learn.microsoft.com/en-us/windows/win32/sysinfo/acquiring-high-resolution-time-stamps
+    // Is the performance counter monotonic (non-decreasing)?
+    // Yes. QPC does not go backward.
+    UNINITIALIZED LARGE_INTEGER buffer;
+    // On systems that run Windows XP or later, the function will always
+    // succeed and will thus never return zero.
+    ::QueryPerformanceCounter(&buffer);
+    long long freq = get_ticks_per_second();
+    long long ticks = buffer.QuadPart;
+    long long tv_sec = ticks / freq;
+    long long tv_nsec = (ticks % freq) * 1_s_ns / freq;
+    ts->tv_sec = static_cast<decltype(ts->tv_sec)>(tv_sec);
----------------
SchrodingerZhu wrote:

addressed

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


More information about the libc-commits mailing list