Skip to content

Commit 6be6d2b

Browse files
committed
Add time.cpp implementation in target_windows
1 parent 5dfa4e6 commit 6be6d2b

File tree

1 file changed

+101
-0
lines changed
  • src/internal_modules/roc_core/target_windows/roc_core

1 file changed

+101
-0
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright (c) 2015 Roc Streaming authors
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
7+
*/
8+
9+
#include "roc_core/time.h"
10+
#include "roc_core/errno_to_str.h"
11+
#include "roc_core/panic.h"
12+
13+
#include <windows.h>
14+
15+
// Present when compiling with MinGW in Windows,
16+
// but not defined when cross-compiling from Linux (Debian 12)
17+
#ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
18+
#define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION (0x00000002)
19+
#endif
20+
21+
namespace roc {
22+
namespace core {
23+
24+
namespace {
25+
26+
#if defined(CLOCK_REALTIME)
27+
28+
clockid_t map_clock(clock_t clock) {
29+
if (clock == ClockMonotonic) {
30+
#if defined(CLOCK_MONOTONIC)
31+
return CLOCK_MONOTONIC;
32+
#endif
33+
}
34+
35+
return CLOCK_REALTIME;
36+
}
37+
38+
#endif
39+
40+
} // namespace
41+
42+
nanoseconds_t timestamp(clock_t clock) {
43+
timespec ts;
44+
if (clock_gettime(map_clock(clock), &ts) == -1) {
45+
roc_panic("time: clock_gettime(): %s", errno_to_str().c_str());
46+
}
47+
48+
return nanoseconds_t(ts.tv_sec) * 1000000000 + nanoseconds_t(ts.tv_nsec);
49+
}
50+
51+
void sleep_for(clock_t clock, nanoseconds_t ns) {
52+
// TODO: handle fallback to non high-resolution timer? (waitable high resolution timer
53+
// supported only from W10 1803)
54+
HANDLE hTimer = CreateWaitableTimerEx(
55+
NULL, NULL, CREATE_WAITABLE_TIMER_HIGH_RESOLUTION, TIMER_ALL_ACCESS);
56+
if (!hTimer) {
57+
roc_panic("time: CreateWaitableTimerEx(): %s", errno_to_str().c_str());
58+
}
59+
LARGE_INTEGER dueTime;
60+
dueTime.QuadPart = ns / -100; // In 100 nanoseconds interval, negative = relative
61+
// value.
62+
// should we add -1 to round for "at least" xx ns?
63+
if (!SetWaitableTimer(hTimer, &dueTime, 0 /*once*/, NULL, NULL, FALSE)) {
64+
roc_panic("time: SetWaitableTimer(): %s", errno_to_str().c_str());
65+
}
66+
if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0) {
67+
roc_panic("time: WaitForSingleObject(): %s", errno_to_str().c_str());
68+
}
69+
CloseHandle(hTimer);
70+
}
71+
72+
void sleep_until(clock_t clock, nanoseconds_t ns) {
73+
nanoseconds_t now = timestamp(clock);
74+
if (ns > now) {
75+
sleep_for(clock, ns - now);
76+
}
77+
}
78+
79+
std::tm nanoseconds_2_tm(nanoseconds_t timestamp) {
80+
const time_t sec = time_t(timestamp / Second);
81+
82+
std::tm tm;
83+
errno_t err = localtime_s(&tm, &sec);
84+
if (err)
85+
roc_panic("time: localtime_s(): %s", errno_to_str(err).c_str());
86+
87+
return tm;
88+
}
89+
90+
nanoseconds_t tm_2_nanoseconds(std::tm tm) {
91+
const time_t sec = mktime(&tm);
92+
93+
if (sec == (time_t)-1) {
94+
roc_panic("time: mktime(): %s", errno_to_str().c_str());
95+
}
96+
97+
return nanoseconds_t(sec) * Second;
98+
}
99+
100+
} // namespace core
101+
} // namespace roc

0 commit comments

Comments
 (0)