C/C++ API Reference
Loading...
Searching...
No Matches
system_clock.h
1// Copyright 2020 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14#pragma once
15
16#include <stddef.h>
17#include <stdint.h>
18
19#include "pw_preprocessor/util.h"
20
21// The backend implements this header to provide the following SystemClock
22// parameters, for more detail on the parameters see the SystemClock usage of
23// them below:
24// PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_NUMERATOR
25// PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_DENOMINATOR
26// constexpr pw::chrono::Epoch pw::chrono::backend::kSystemClockEpoch;
27// constexpr bool pw::chrono::backend::kSystemClockFreeRunning;
28// constexpr bool pw::chrono::backend::kSystemClockNmiSafe;
29#include "pw_chrono_backend/system_clock_config.h"
30
31#ifdef __cplusplus
32
33#include <chrono>
34#include <ratio>
35
36#include "pw_chrono/virtual_clock.h"
37#include "pw_numeric/saturating_arithmetic.h"
38
40namespace pw::chrono {
41
43
44namespace backend {
45
52
53} // namespace backend
54
86 using rep = int64_t;
88 using period = std::ratio<PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_NUMERATOR,
89 PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_DENOMINATOR>;
91 using duration = std::chrono::duration<rep, period>;
92 using time_point = std::chrono::time_point<SystemClock>;
94 static constexpr Epoch epoch = backend::kSystemClockEpoch;
95
99 static constexpr bool is_monotonic = true;
100 static constexpr bool is_steady = false;
101
104 static constexpr bool is_free_running = backend::kSystemClockFreeRunning;
105
107 static constexpr bool is_stopped_in_halting_debug_mode = true;
108
110 static constexpr bool is_always_enabled = true;
111
115 static constexpr bool is_nmi_safe = backend::kSystemClockNmiSafe;
116
118 static time_point now() noexcept {
119 return time_point(duration(backend::GetSystemClockTickCount()));
120 }
121
125 template <class Rep, class Period>
126 static constexpr duration for_at_least(std::chrono::duration<Rep, Period> d) {
127 return std::chrono::ceil<duration>(d);
128 }
129
137 static time_point TimePointAfterAtLeast(duration after_at_least) {
138 rep ticks = backend::GetSystemClockTickCount() + 1;
139 return time_point(duration(add_sat(ticks, after_at_least.count())));
140 }
141};
142
143// NOTE: VirtualClock here is specialized on SystemClock in order to provide
144// the `RealClock` function.
145//
146// SystemClock is defined in this file, so there's no risk of an ODR violation
147// as other libraries are unable to spell VirtualClock<SystemClock> unless
148// they have first included this file.
149
179template <>
181 public:
184
185 virtual ~VirtualClock() = default;
186
188 virtual SystemClock::time_point now() = 0;
189};
190
192
193} // namespace pw::chrono
194
195// The backend can opt to include an inlined implementation of the following:
196// int64_t GetSystemClockTickCount();
197#if __has_include("pw_chrono_backend/system_clock_inline.h")
198#include "pw_chrono_backend/system_clock_inline.h"
199#endif // __has_include("pw_chrono_backend/system_clock_inline.h")
200
201#endif // __cplusplus
202
203// C API Users should not create pw_chrono_SystemClock_Duration's directly,
204// instead it is strongly recommended to use macros which express the duration
205// in time units, instead of non-portable ticks.
206//
207// The following macros round up just like std::chrono::ceil, this is the
208// recommended rounding to maintain the "at least" contract of timeouts and
209// deadlines (note the *_CEIL macros are the same only more explicit):
210// PW_SYSTEM_CLOCK_MS(milliseconds)
211// PW_SYSTEM_CLOCK_S(seconds)
212// PW_SYSTEM_CLOCK_MIN(minutes)
213// PW_SYSTEM_CLOCK_H(hours)
214// PW_SYSTEM_CLOCK_MS_CEIL(milliseconds)
215// PW_SYSTEM_CLOCK_S_CEIL(seconds)
216// PW_SYSTEM_CLOCK_MIN_CEIL(minutes)
217// PW_SYSTEM_CLOCK_H_CEIL(hours)
218//
219// The following macros round down like std::chrono::{floor,duration_cast},
220// these are discouraged but sometimes necessary:
221// PW_SYSTEM_CLOCK_MS_FLOOR(milliseconds)
222// PW_SYSTEM_CLOCK_S_FLOOR(seconds)
223// PW_SYSTEM_CLOCK_MIN_FLOOR(minutes)
224// PW_SYSTEM_CLOCK_H_FLOOR(hours)
225#include "pw_chrono/internal/system_clock_macros.h"
226
227PW_EXTERN_C_START
228
229typedef struct {
230 int64_t ticks;
232
233typedef struct {
234 pw_chrono_SystemClock_Duration duration_since_epoch;
236typedef int64_t pw_chrono_SystemClock_Nanoseconds;
237
238// Returns the current time, see SystemClock::now() for more detail.
239pw_chrono_SystemClock_TimePoint pw_chrono_SystemClock_Now(void);
240
241// Returns the change in time between the current_time - last_time.
242pw_chrono_SystemClock_Duration pw_chrono_SystemClock_TimeElapsed(
245
246// For lossless time unit conversion, the seconds per tick ratio that is
247// numerator/denominator should be used:
248// PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_NUMERATOR
249// PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_DENOMINATOR
250
251// Warning, this may be lossy due to the use of std::chrono::floor,
252// rounding towards zero.
253pw_chrono_SystemClock_Nanoseconds pw_chrono_SystemClock_DurationToNsFloor(
255
256PW_EXTERN_C_END
Definition: system_clock.h:180
Definition: virtual_clock.h:31
static constexpr Epoch epoch
The epoch must be provided by the backend.
Definition: system_clock.h:94
static constexpr bool is_nmi_safe
Definition: system_clock.h:115
int64_t GetSystemClockTickCount()
static constexpr bool is_monotonic
Definition: system_clock.h:99
static constexpr duration for_at_least(std::chrono::duration< Rep, Period > d)
Definition: system_clock.h:126
virtual SystemClock::time_point now()=0
Returns the current time.
static constexpr bool is_stopped_in_halting_debug_mode
The clock must stop while in halting debug mode.
Definition: system_clock.h:107
static time_point now() noexcept
This is thread and IRQ safe. This must be provided by the backend.
Definition: system_clock.h:118
static VirtualClock< SystemClock > & RealClock()
Returns a reference to the real system clock to aid instantiation.
static time_point TimePointAfterAtLeast(duration after_at_least)
Definition: system_clock.h:137
static constexpr bool is_free_running
Definition: system_clock.h:104
std::ratio< PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_NUMERATOR, PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_DENOMINATOR > period
The period must be provided by the backend.
Definition: system_clock.h:89
std::chrono::duration< rep, period > duration
Alias for durations representable with this clock.
Definition: system_clock.h:91
static constexpr bool is_always_enabled
The now() function can be invoked at any time.
Definition: system_clock.h:110
constexpr T add_sat(T lhs, T rhs) noexcept
Definition: saturating_arithmetic.h:53
Portable std::chrono library for embedded.
Definition: simulated_system_clock.h:22
Definition: system_clock.h:85
Definition: system_clock.h:229
Definition: system_clock.h:233