Skip to content

Commit 7bf98be

Browse files
address CRs
1 parent c7e61ba commit 7bf98be

File tree

5 files changed

+41
-18
lines changed

5 files changed

+41
-18
lines changed

libc/hdr/time_macros.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,10 @@
1919

2020
#endif // LLVM_LIBC_FULL_BUILD
2121

22+
// TODO: For now, on windows, let's always include the extension header.
23+
// We will need to decide how to export this header.
24+
#ifdef _WIN32
25+
#include "include/llvm-libc-macros/windows/time-macros-ext.h"
26+
#endif // _WIN32
27+
2228
#endif // LLVM_LIBC_HDR_TIME_MACROS_H

libc/hdr/types/clockid_t.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
#ifndef LLVM_LIBC_HDR_TYPES_CLOCKID_T_H
1010
#define LLVM_LIBC_HDR_TYPES_CLOCKID_T_H
1111

12-
#if defined(LIBC_FULL_BUILD) || defined(_MSC_VER)
12+
// TODO: we will need to decide how to export extension to windows.
13+
#if defined(LIBC_FULL_BUILD) || defined(_WIN32)
1314

1415
#include "include/llvm-libc-types/clockid_t.h"
1516

libc/src/__support/time/windows/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ add_object_library(
1313
libc.src.__support.error_or
1414
libc.src.__support.OSUtil.osutil
1515
libc.src.__support.CPP.atomic
16+
libc.src.__support.CPP.limits
1617
)

libc/src/__support/time/windows/clock_gettime.cpp

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,29 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include "src/__support/time/clock_gettime.h"
10-
#include "include/llvm-libc-macros/windows/time-macros-ext.h"
9+
#include "hdr/time_macros.h"
10+
1111
#include "src/__support/CPP/atomic.h"
1212
#include "src/__support/CPP/bit.h"
13+
#include "src/__support/CPP/limits.h"
14+
#include "src/__support/macros/optimization.h"
15+
#include "src/__support/time/clock_gettime.h"
1316
#include "src/__support/time/units.h"
14-
#include <Windows.h>
1517

16-
#ifdef __clang__
17-
#define UNINITIALIZED [[clang::uninitialized]]
18-
#else
19-
#define UNINITIALIZED
20-
#endif
18+
#define WIN32_LEAN_AND_MEAN
19+
#define NOMINMAX
20+
#include <Windows.h>
2121

2222
namespace LIBC_NAMESPACE_DECL {
2323
namespace internal {
2424
static long long get_ticks_per_second() {
2525
static cpp::Atomic<long long> frequency = 0;
26+
// Relaxed ordering is enough. It is okay to record the frequency multiple
27+
// times. The store operation itself is atomic and the value must propagate
28+
// as required by cache coherence.
2629
auto freq = frequency.load(cpp::MemoryOrder::RELAXED);
2730
if (!freq) {
28-
UNINITIALIZED LARGE_INTEGER buffer;
31+
[[clang::uninitialized]] LARGE_INTEGER buffer;
2932
// On systems that run Windows XP or later, the function will always
3033
// succeed and will thus never return zero.
3134
::QueryPerformanceFrequency(&buffer);
@@ -37,6 +40,8 @@ static long long get_ticks_per_second() {
3740

3841
ErrorOr<int> clock_gettime(clockid_t clockid, timespec *ts) {
3942
using namespace time_units;
43+
constexpr long long SEC_LIMIT =
44+
cpp::numeric_limits<decltype(ts->tv_sec)>::max();
4045
ErrorOr<int> ret = 0;
4146
switch (clockid) {
4247
default:
@@ -48,14 +53,18 @@ ErrorOr<int> clock_gettime(clockid_t clockid, timespec *ts) {
4853
// https://learn.microsoft.com/en-us/windows/win32/sysinfo/acquiring-high-resolution-time-stamps
4954
// Is the performance counter monotonic (non-decreasing)?
5055
// Yes. QPC does not go backward.
51-
UNINITIALIZED LARGE_INTEGER buffer;
56+
[[clang::uninitialized]] LARGE_INTEGER buffer;
5257
// On systems that run Windows XP or later, the function will always
5358
// succeed and will thus never return zero.
5459
::QueryPerformanceCounter(&buffer);
5560
long long freq = get_ticks_per_second();
5661
long long ticks = buffer.QuadPart;
5762
long long tv_sec = ticks / freq;
5863
long long tv_nsec = (ticks % freq) * 1_s_ns / freq;
64+
if (LIBC_UNLIKELY(tv_sec > SEC_LIMIT)) {
65+
ret = cpp::unexpected(EOVERFLOW);
66+
break;
67+
}
5968
ts->tv_sec = static_cast<decltype(ts->tv_sec)>(tv_sec);
6069
ts->tv_nsec = static_cast<decltype(ts->tv_nsec)>(tv_nsec);
6170
break;
@@ -65,17 +74,27 @@ ErrorOr<int> clock_gettime(clockid_t clockid, timespec *ts) {
6574
// GetSystemTimePreciseAsFileTime
6675
// This function is best suited for high-resolution time-of-day
6776
// measurements, or time stamps that are synchronized to UTC
68-
UNINITIALIZED FILETIME file_time;
69-
UNINITIALIZED ULARGE_INTEGER time;
77+
[[clang::uninitialized]] FILETIME file_time;
78+
[[clang::uninitialized]] ULARGE_INTEGER time;
7079
::GetSystemTimePreciseAsFileTime(&file_time);
7180
time.LowPart = file_time.dwLowDateTime;
7281
time.HighPart = file_time.dwHighDateTime;
7382

7483
// adjust to POSIX epoch (from Jan 1, 1601 to Jan 1, 1970)
7584
constexpr unsigned long long HNS_PER_SEC = 1_s_ns / 100ULL;
85+
constexpr unsigned long long POSIX_TIME_SHIFT =
86+
(11644473600ULL * HNS_PER_SEC);
87+
if (LIBC_UNLIKELY(POSIX_TIME_SHIFT > time.QuadPart)) {
88+
ret = cpp::unexpected(EOVERFLOW);
89+
break;
90+
}
7691
time.QuadPart -= (11644473600ULL * HNS_PER_SEC);
7792
unsigned long long tv_sec = time.QuadPart / HNS_PER_SEC;
7893
unsigned long long tv_nsec = (time.QuadPart % HNS_PER_SEC) * 100ULL;
94+
if (LIBC_UNLIKELY(tv_sec > SEC_LIMIT)) {
95+
ret = cpp::unexpected(EOVERFLOW);
96+
break;
97+
}
7998
ts->tv_sec = static_cast<decltype(ts->tv_sec)>(tv_sec);
8099
ts->tv_nsec = static_cast<decltype(ts->tv_nsec)>(tv_nsec);
81100
break;

libc/src/time/time.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,8 @@
1313
#include "src/errno/libc_errno.h"
1414
#include "src/time/time_func.h"
1515

16-
#ifdef _MSC_VER
17-
#include "include/llvm-libc-macros/windows/time-macros-ext.h"
18-
#endif
19-
2016
namespace LIBC_NAMESPACE_DECL {
21-
LLVM_LIBC_FUNCTION(time_t, time, (time_t * tp)) {
17+
LLVM_LIBC_FUNCTION(time_t, time, (time_t *tp)) {
2218
struct timespec ts;
2319
auto result = internal::clock_gettime(CLOCK_REALTIME, &ts);
2420
if (!result.has_value()) {

0 commit comments

Comments
 (0)