pw_chrono: Improve SystemClock C API
Changes the SystemClock C Api to:
1) Use a pw_chrono_SystemClock_Duration struct instead of aliasing
an int64_t under pw_chrono_SystemClock_TickCount which could
accidentally permit direct tick usage.
2) Add PW_SYSTEM_CLOCK_{MS,S,MIN,H} and
PW_SYSTEM_CLOCK_{MS,S,MIN,H}_CEIL to permit C API users to
create durations which round up to the nearest tick for deadlines
and timeouts, mirroring std::chrono::ceil.
3) Add PW_SYSTEM_CLOCK_{MS,S,MIN,H}_FLOOR to permit C API users to
create durations which round down to the nearest tick for oddball
corner cases, mirroring std::chrono::floor.
4) In order to enable said macros, the system_clock_config.h backend
config was changed to require the clock period as a preprocessor
defines instead of a std::ratio<>.
5) Renames pw_chrono_SystemClock_TimeDelta to
pw_chrono_SystemClock_TimeElapsed to make the argument ordering
make more sense.
6) Changes existing std::chrono::duration_cast usage to
std::chrono::ceil and std::chrono:floor to set a good example
to be explicit on rounding.
7) Renames pw_chrono_SystemClock_TickCountsToNsTruncate accordingly to
pw_chrono_SystemClock_DurationToNsFloor.
Requires: pigweed-internal:9340
Change-Id: Ia628dceac53f964eda7c4aacd3d790b8b0e92207
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/31280
Commit-Queue: Ewout van Bekkum <ewout@google.com>
Reviewed-by: Wyatt Hepler <hepler@google.com>
diff --git a/pw_chrono/BUILD b/pw_chrono/BUILD
index b13b14f..7bc077b 100644
--- a/pw_chrono/BUILD
+++ b/pw_chrono/BUILD
@@ -36,6 +36,7 @@
pw_cc_library(
name = "system_clock_facade",
hdrs = [
+ "public/pw_chrono/internal/system_clock_macros.h",
"public/pw_chrono/system_clock.h",
],
includes = ["public"],
diff --git a/pw_chrono/BUILD.gn b/pw_chrono/BUILD.gn
index 9eda0d7..8ed15db 100644
--- a/pw_chrono/BUILD.gn
+++ b/pw_chrono/BUILD.gn
@@ -32,7 +32,10 @@
pw_facade("system_clock") {
backend = pw_chrono_SYSTEM_CLOCK_BACKEND
public_configs = [ ":public_include_path" ]
- public = [ "public/pw_chrono/system_clock.h" ]
+ public = [
+ "public/pw_chrono/internal/system_clock_macros.h",
+ "public/pw_chrono/system_clock.h",
+ ]
public_deps = [
":epoch",
"$dir_pw_preprocessor",
diff --git a/pw_chrono/public/pw_chrono/internal/system_clock_macros.h b/pw_chrono/public/pw_chrono/internal/system_clock_macros.h
new file mode 100644
index 0000000..623ec9b
--- /dev/null
+++ b/pw_chrono/public/pw_chrono/internal/system_clock_macros.h
@@ -0,0 +1,61 @@
+// Copyright 2020 The Pigweed Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+#pragma once
+
+#define _PW_SYSTEM_CLOCK_DURATION(num_ticks) \
+ ((pw_chrono_SystemClock_Duration){.ticks = (num_ticks)})
+
+// clang-format off
+
+// ticks_ceil = ((count * clock_period_den + time_unit_num - 1) * time_unit_den) /
+// (clock_period_num * time_unit_num)
+#define _PW_SYSTEM_CLOCK_TIME_TO_DURATION_CEIL( \
+ count, time_unit_seconds_numerator, time_unit_seconds_denominator) \
+ _PW_SYSTEM_CLOCK_DURATION( \
+ (((int64_t)(count) * PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_DENOMINATOR + time_unit_seconds_numerator - 1) * time_unit_seconds_denominator) / \
+ (PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_NUMERATOR * time_unit_seconds_numerator))
+
+// ticks_floor = (count * clock_period_den * time_unit_den) /
+// (clock_period_num * time_unit_num)
+#define _PW_SYSTEM_CLOCK_TIME_TO_DURATION_FLOOR( \
+ count, time_unit_seconds_numerator, time_unit_seconds_denominator) \
+ _PW_SYSTEM_CLOCK_DURATION( \
+ ((int64_t)(count) * PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_DENOMINATOR * time_unit_seconds_denominator) / \
+ (PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_NUMERATOR * time_unit_seconds_numerator))
+
+
+#define PW_SYSTEM_CLOCK_MS_CEIL(milliseconds) \
+ _PW_SYSTEM_CLOCK_TIME_TO_DURATION_CEIL(milliseconds, 1000, 1)
+#define PW_SYSTEM_CLOCK_S_CEIL(seconds) \
+ _PW_SYSTEM_CLOCK_TIME_TO_DURATION_CEIL(seconds, 1, 1)
+#define PW_SYSTEM_CLOCK_MIN_CEIL(minutes) \
+ _PW_SYSTEM_CLOCK_TIME_TO_DURATION_CEIL(minutes, 1, 60)
+#define PW_SYSTEM_CLOCK_H_CEIL(hours) \
+ _PW_SYSTEM_CLOCK_TIME_TO_DURATION_CEIL(hours, 1, 60 * 60)
+
+#define PW_SYSTEM_CLOCK_MS_FLOOR(milliseconds) \
+ _PW_SYSTEM_CLOCK_TIME_TO_DURATION_FLOOR(milliseconds, 1000, 1)
+#define PW_SYSTEM_CLOCK_S_FLOOR(seconds) \
+ _PW_SYSTEM_CLOCK_TIME_TO_DURATION_FLOOR(seconds, 1, 1)
+#define PW_SYSTEM_CLOCK_MIN_FLOOR(minutes) \
+ _PW_SYSTEM_CLOCK_TIME_TO_DURATION_FLOOR(minutes, 1, 60)
+#define PW_SYSTEM_CLOCK_H_FLOOR(hours) \
+ _PW_SYSTEM_CLOCK_TIME_TO_DURATION_FLOOR(hours, 1, 60 * 60)
+
+// clang-format on
+
+#define PW_SYSTEM_CLOCK_MS(milliseconds) PW_SYSTEM_CLOCK_MS_CEIL(milliseconds)
+#define PW_SYSTEM_CLOCK_S(seconds) PW_SYSTEM_CLOCK_S_CEIL(seconds)
+#define PW_SYSTEM_CLOCK_MIN(minutes) PW_SYSTEM_CLOCK_MIN_CEIL(minutes)
+#define PW_SYSTEM_CLOCK_H(hours) PW_SYSTEM_CLOCK_H_CEIL(hours)
diff --git a/pw_chrono/public/pw_chrono/system_clock.h b/pw_chrono/public/pw_chrono/system_clock.h
index 36481c2..39093e2 100644
--- a/pw_chrono/public/pw_chrono/system_clock.h
+++ b/pw_chrono/public/pw_chrono/system_clock.h
@@ -18,19 +18,21 @@
#include "pw_preprocessor/util.h"
-#ifdef __cplusplus
-
-#include <chrono>
-
// The backend implements this header to provide the following SystemClock
// parameters, for more detail on the parameters see the SystemClock usage of
// them below:
-// std::ratio<> typed pw::chrono::backend::SystemClockPeriodSecondsRatio type
+// PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_NUMERATOR
+// PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_DENOMINATOR
// constexpr pw::chrono::Epoch pw::chrono::backend::kSystemClockEpoch;
// constexpr bool pw::chrono::backend::kSystemClockFreeRunning;
// constexpr bool pw::chrono::backend::kSystemClockNmiSafe;
#include "pw_chrono_backend/system_clock_config.h"
+#ifdef __cplusplus
+
+#include <chrono>
+#include <ratio>
+
namespace pw::chrono {
namespace backend {
@@ -72,7 +74,8 @@
struct SystemClock {
using rep = int64_t;
// The period must be provided by the backend.
- using period = backend::SystemClockPeriodSecondsRatio;
+ using period = std::ratio<PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_NUMERATOR,
+ PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_DENOMINATOR>;
using duration = std::chrono::duration<rep, period>;
using time_point = std::chrono::time_point<SystemClock>;
// The epoch must be provided by the backend.
@@ -152,9 +155,36 @@
PW_EXTERN_C_START
-typedef int64_t pw_chrono_SystemClock_TickCount;
+// C API Users should not create pw_chrono_SystemClock_Duration's directly,
+// instead it is strongly recommended to use macros which express the duration
+// in time units, instead of non-portable ticks.
+//
+// The following macros round up just like std::chrono::ceil, this is the
+// recommended rounding to maintain the "at least" contract of timeouts and
+// deadlines (note the *_CEIL macros are the same only more explicit):
+// PW_SYSTEM_CLOCK_MS(milliseconds)
+// PW_SYSTEM_CLOCK_S(seconds)
+// PW_SYSTEM_CLOCK_MIN(minutes)
+// PW_SYSTEM_CLOCK_H(hours)
+// PW_SYSTEM_CLOCK_MS_CEIL(milliseconds)
+// PW_SYSTEM_CLOCK_S_CEIL(seconds)
+// PW_SYSTEM_CLOCK_MIN_CEIL(minutes)
+// PW_SYSTEM_CLOCK_H_CEIL(hours)
+//
+// The following macros round down like std::chrono::{floor,duration_cast},
+// these are discouraged but sometimes necessary:
+// PW_SYSTEM_CLOCK_MS_FLOOR(milliseconds)
+// PW_SYSTEM_CLOCK_S_FLOOR(seconds)
+// PW_SYSTEM_CLOCK_MIN_FLOOR(minutes)
+// PW_SYSTEM_CLOCK_H_FLOOR(hours)
+#include "pw_chrono/internal/system_clock_macros.h"
+
typedef struct {
- pw_chrono_SystemClock_TickCount ticks_since_epoch;
+ int64_t ticks;
+} pw_chrono_SystemClock_Duration;
+
+typedef struct {
+ pw_chrono_SystemClock_Duration duration_since_epoch;
} pw_chrono_SystemClock_TimePoint;
typedef int64_t pw_chrono_SystemClock_Nanoseconds;
@@ -162,18 +192,18 @@
pw_chrono_SystemClock_TimePoint pw_chrono_SystemClock_Now();
// Returns the change in time between the current_time - last_time.
-pw_chrono_SystemClock_TickCount pw_chrono_SystemClock_TimeDelta(
+pw_chrono_SystemClock_Duration pw_chrono_SystemClock_TimeElapsed(
pw_chrono_SystemClock_TimePoint last_time,
pw_chrono_SystemClock_TimePoint current_time);
// For lossless time unit conversion, the seconds per tick ratio that is
-// numerator/denominator should be used.
-int32_t pw_chrono_SystemClock_PeriodSeconds_Numerator();
-int32_t pw_chrono_SystemClock_PeriodSeconds_Denominator();
+// numerator/denominator should be used:
+// PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_NUMERATOR
+// PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_DENOMINATOR
-// Warning, this may be lossy due to the use of std::chrono::duration_cast,
+// Warning, this may be lossy due to the use of std::chrono::floor,
// rounding towards zero.
-pw_chrono_SystemClock_Nanoseconds pw_chrono_SystemClock_TickCountToNsTruncate(
- pw_chrono_SystemClock_TickCount ticks);
+pw_chrono_SystemClock_Nanoseconds pw_chrono_SystemClock_DurationToNsFloor(
+ pw_chrono_SystemClock_Duration duration);
PW_EXTERN_C_END
diff --git a/pw_chrono/simulated_system_clock_test.cc b/pw_chrono/simulated_system_clock_test.cc
index 5102a99..f7d4fe8 100644
--- a/pw_chrono/simulated_system_clock_test.cc
+++ b/pw_chrono/simulated_system_clock_test.cc
@@ -16,15 +16,16 @@
#include "gtest/gtest.h"
+using namespace std::chrono_literals;
+
namespace pw::chrono {
namespace {
-constexpr auto kArbitraryDuration = std::chrono::hours(42);
// We can't control the SystemClock's period configuration, so just in case
// 42 hours cannot be accurately expressed in integer ticks, round the
-// duration w/ duration_cast.
+// duration w/ ceil.
constexpr auto kRoundedArbitraryDuration =
- std::chrono::duration_cast<SystemClock::duration>(kArbitraryDuration);
+ std::chrono::ceil<SystemClock::duration>(42h);
TEST(SimulatedSystemClock, InitialTime) {
SimulatedSystemClock clock;
diff --git a/pw_chrono/system_clock.cc b/pw_chrono/system_clock.cc
index cbf8d45..14a2f28 100644
--- a/pw_chrono/system_clock.cc
+++ b/pw_chrono/system_clock.cc
@@ -32,28 +32,22 @@
} // namespace pw::chrono
extern "C" pw_chrono_SystemClock_TimePoint pw_chrono_SystemClock_Now() {
- return {.ticks_since_epoch =
- pw::chrono::SystemClock::now().time_since_epoch().count()};
+ return {
+ .duration_since_epoch = {
+ .ticks = pw::chrono::SystemClock::now().time_since_epoch().count()}};
}
-extern "C" pw_chrono_SystemClock_TickCount pw_chrono_SystemClock_TimeDelta(
+extern "C" pw_chrono_SystemClock_Duration pw_chrono_SystemClock_TimeElapsed(
pw_chrono_SystemClock_TimePoint last_time,
pw_chrono_SystemClock_TimePoint current_time) {
- return current_time.ticks_since_epoch - last_time.ticks_since_epoch;
-}
-
-extern "C" int32_t pw_chrono_SystemClock_PeriodSeconds_Numerator() {
- return pw::chrono::SystemClock::period::num;
-}
-
-extern "C" int32_t pw_chrono_SystemClock_PeriodSeconds_Denominator() {
- return pw::chrono::SystemClock::period::den;
+ return {.ticks = current_time.duration_since_epoch.ticks -
+ last_time.duration_since_epoch.ticks};
}
extern "C" pw_chrono_SystemClock_Nanoseconds
-pw_chrono_SystemClock_TickCountToNsTruncate(
- pw_chrono_SystemClock_TickCount ticks) {
- return std::chrono::duration_cast<std::chrono::nanoseconds>(
- pw::chrono::SystemClock::duration(ticks))
+pw_chrono_SystemClock_DurationToNsFloor(
+ pw_chrono_SystemClock_Duration duration) {
+ return std::chrono::floor<std::chrono::nanoseconds>(
+ pw::chrono::SystemClock::duration(duration.ticks))
.count();
}
diff --git a/pw_chrono/system_clock_facade_test.cc b/pw_chrono/system_clock_facade_test.cc
index 1d60b11..af17a65 100644
--- a/pw_chrono/system_clock_facade_test.cc
+++ b/pw_chrono/system_clock_facade_test.cc
@@ -18,6 +18,8 @@
#include "pw_chrono/system_clock.h"
#include "pw_preprocessor/util.h"
+using namespace std::chrono_literals;
+
namespace pw::chrono {
namespace {
@@ -25,16 +27,12 @@
// Functions defined in system_clock_facade_test_c.c which call the API from C.
pw_chrono_SystemClock_TimePoint pw_chrono_SystemClock_CallNow();
-pw_chrono_SystemClock_TickCount pw_chrono_SystemClock_CallTimeDelta(
+pw_chrono_SystemClock_Duration pw_chrono_SystemClock_CallTimeElapsed(
pw_chrono_SystemClock_TimePoint last_time,
pw_chrono_SystemClock_TimePoint current_time);
-int32_t pw_chrono_SystemClock_PeriodSeconds_CallNumerator();
-int32_t pw_chrono_SystemClock_PeriodSeconds_CallDenominator();
-
-pw_chrono_SystemClock_Nanoseconds
-pw_chrono_SystemClock_CallTickCountToNsTruncate(
- pw_chrono_SystemClock_TickCount ticks);
+pw_chrono_SystemClock_Nanoseconds pw_chrono_SystemClock_CallDurationToNsFloor(
+ pw_chrono_SystemClock_Duration ticks);
} // extern "C"
@@ -81,8 +79,8 @@
// Verify the clock moves forward.
bool clock_moved_forward = false;
for (uint64_t i = 0; i < kMaxIterations; ++i) {
- if (pw_chrono_SystemClock_CallNow().ticks_since_epoch >
- start_time.ticks_since_epoch) {
+ if (pw_chrono_SystemClock_CallNow().duration_since_epoch.ticks >
+ start_time.duration_since_epoch.ticks) {
clock_moved_forward = true;
break;
}
@@ -90,32 +88,26 @@
EXPECT_TRUE(clock_moved_forward);
}
-TEST(SystemClock, TimeDeltaInC) {
+TEST(SystemClock, TimeElapsedInC) {
const pw_chrono_SystemClock_TimePoint first = pw_chrono_SystemClock_CallNow();
const pw_chrono_SystemClock_TimePoint last = pw_chrono_SystemClock_CallNow();
static_assert(SystemClock::is_monotonic);
- EXPECT_GE(0, pw_chrono_SystemClock_CallTimeDelta(last, first));
-}
-
-TEST(SystemClock, PeriodRatioInC) {
- EXPECT_EQ(SystemClock::period::num,
- pw_chrono_SystemClock_PeriodSeconds_CallNumerator());
- EXPECT_EQ(SystemClock::period::den,
- pw_chrono_SystemClock_PeriodSeconds_CallDenominator());
+ EXPECT_GE(0, pw_chrono_SystemClock_CallTimeElapsed(last, first).ticks);
}
TEST(SystemClock, DurationCastInC) {
- static constexpr auto kArbitraryPeriod = std::chrono::hours(42);
// We can't control the SystemClock's period configuration, so just in case
// 42 hours cannot be accurately expressed in integer ticks, round the
- // duration w/ duration_cast.
+ // duration w/ floor.
static constexpr auto kRoundedArbitraryDuration =
- std::chrono::duration_cast<SystemClock::duration>(kArbitraryPeriod);
- EXPECT_EQ(std::chrono::duration_cast<std::chrono::nanoseconds>(
- kRoundedArbitraryDuration)
- .count(),
- pw_chrono_SystemClock_CallTickCountToNsTruncate(
- kRoundedArbitraryDuration.count()));
+ std::chrono::floor<SystemClock::duration>(42h);
+ static constexpr pw_chrono_SystemClock_Duration kRoundedArbitraryDurationInC =
+ PW_SYSTEM_CLOCK_H_FLOOR(42);
+ EXPECT_EQ(
+ std::chrono::floor<std::chrono::nanoseconds>(kRoundedArbitraryDuration)
+ .count(),
+ pw_chrono_SystemClock_CallDurationToNsFloor(
+ kRoundedArbitraryDurationInC));
}
} // namespace
diff --git a/pw_chrono/system_clock_facade_test_c.c b/pw_chrono/system_clock_facade_test_c.c
index 1ae3456..117d6d7 100644
--- a/pw_chrono/system_clock_facade_test_c.c
+++ b/pw_chrono/system_clock_facade_test_c.c
@@ -21,22 +21,13 @@
return pw_chrono_SystemClock_Now();
}
-pw_chrono_SystemClock_TickCount pw_chrono_SystemClock_CallTimeDelta(
+pw_chrono_SystemClock_Duration pw_chrono_SystemClock_CallTimeElapsed(
pw_chrono_SystemClock_TimePoint last_time,
pw_chrono_SystemClock_TimePoint current_time) {
- return pw_chrono_SystemClock_TimeDelta(last_time, current_time);
+ return pw_chrono_SystemClock_TimeElapsed(last_time, current_time);
}
-int32_t pw_chrono_SystemClock_PeriodSeconds_CallNumerator() {
- return pw_chrono_SystemClock_PeriodSeconds_Numerator();
-}
-
-int32_t pw_chrono_SystemClock_PeriodSeconds_CallDenominator() {
- return pw_chrono_SystemClock_PeriodSeconds_Denominator();
-}
-
-pw_chrono_SystemClock_Nanoseconds
-pw_chrono_SystemClock_CallTickCountToNsTruncate(
- pw_chrono_SystemClock_TickCount ticks) {
- return pw_chrono_SystemClock_TickCountToNsTruncate(ticks);
+pw_chrono_SystemClock_Nanoseconds pw_chrono_SystemClock_CallDurationToNsFloor(
+ pw_chrono_SystemClock_Duration ticks) {
+ return pw_chrono_SystemClock_DurationToNsFloor(ticks);
}
diff --git a/pw_chrono_freertos/public/pw_chrono_freertos/system_clock_config.h b/pw_chrono_freertos/public/pw_chrono_freertos/system_clock_config.h
index 348392e..7f8d631 100644
--- a/pw_chrono_freertos/public/pw_chrono_freertos/system_clock_config.h
+++ b/pw_chrono_freertos/public/pw_chrono_freertos/system_clock_config.h
@@ -13,16 +13,18 @@
// the License.
#pragma once
-#include <ratio>
-
#include "FreeRTOS.h"
+
+// Use the FreeRTOS config's tick rate.
+#define PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_NUMERATOR 1
+#define PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_DENOMINATOR configTICK_RATE_HZ
+
+#ifdef __cplusplus
+
#include "pw_chrono/epoch.h"
namespace pw::chrono::backend {
-// Use the FreeRTOS config's tick rate.
-using SystemClockPeriodSecondsRatio = std::ratio<1, configTICK_RATE_HZ>;
-
// The FreeRTOS clock starts at zero during initialization, approximately the
// time since boot.
constexpr inline Epoch kSystemClockEpoch = pw::chrono::Epoch::kTimeSinceBoot;
@@ -34,3 +36,5 @@
constexpr inline bool kSystemClockFreeRunning = false;
} // namespace pw::chrono::backend
+
+#endif // __cplusplus
diff --git a/pw_chrono_stl/public/pw_chrono_stl/system_clock_config.h b/pw_chrono_stl/public/pw_chrono_stl/system_clock_config.h
index 05b1c71..9766fa2 100644
--- a/pw_chrono_stl/public/pw_chrono_stl/system_clock_config.h
+++ b/pw_chrono_stl/public/pw_chrono_stl/system_clock_config.h
@@ -13,15 +13,19 @@
// the License.
#pragma once
-#include <chrono>
+// Ideally we'd use std::chrono::steady_clock::period, however this is not
+// something we can expose to the C API. Instead we assume it has nanosecond
+// compatibility and we rely on implicit conversion to tell us at compile time
+// whether this is incompatible.
+#define PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_NUMERATOR 1
+#define PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_DENOMINATOR 100'000'0000
+
+#ifdef __cplusplus
#include "pw_chrono/epoch.h"
namespace pw::chrono::backend {
-// Provide the native std::chrono::steady_clock period.
-using SystemClockPeriodSecondsRatio = std::chrono::steady_clock::period;
-
// The std::chrono::steady_clock does not have a defined epoch.
constexpr inline Epoch kSystemClockEpoch = pw::chrono::Epoch::kUnknown;
@@ -32,3 +36,5 @@
constexpr inline bool kSystemClockFreeRunning = true;
} // namespace pw::chrono::backend
+
+#endif // __cplusplus
diff --git a/pw_chrono_threadx/public/pw_chrono_threadx/config.h b/pw_chrono_threadx/public/pw_chrono_threadx/config.h
index a4681c5..bfb2109 100644
--- a/pw_chrono_threadx/public/pw_chrono_threadx/config.h
+++ b/pw_chrono_threadx/public/pw_chrono_threadx/config.h
@@ -31,8 +31,10 @@
#define PW_CHRONO_THREADX_CFG_CLOCK_PERIOD_SECONDS_DENOMINATOR 100
#endif // PW_CHRONO_THREADX_CFG_CLOCK_PERIOD_SECONDS_DENOMINATOR
-static_assert(PW_CHRONO_THREADX_CFG_CLOCK_PERIOD_SECONDS_NUMERATOR >= 1);
-static_assert(PW_CHRONO_THREADX_CFG_CLOCK_PERIOD_SECONDS_DENOMINATOR >= 1);
+static_assert(PW_CHRONO_THREADX_CFG_CLOCK_PERIOD_SECONDS_NUMERATOR >= 1,
+ "the numerator must be positive and cannot be fractional");
+static_assert(PW_CHRONO_THREADX_CFG_CLOCK_PERIOD_SECONDS_DENOMINATOR >= 1,
+ "the denominator must be positive and cannot be fractional");
// Because the SystemClock::now() implementation requires the user to invoke it
// more than once per overflow period, the max timeout is set to ensure that
@@ -43,4 +45,5 @@
#endif // PW_CHRONO_THREADX_CFG_MAX_TIMEOUT
static_assert((PW_CHRONO_THREADX_CFG_MAX_TIMEOUT > 0) &&
- (PW_CHRONO_THREADX_CFG_MAX_TIMEOUT <= (TX_WAIT_FOREVER - 1)));
+ (PW_CHRONO_THREADX_CFG_MAX_TIMEOUT <= (TX_WAIT_FOREVER - 1)),
+ "the timeout must be greater than 0 and less than the sentinel");
diff --git a/pw_chrono_threadx/public/pw_chrono_threadx/system_clock_config.h b/pw_chrono_threadx/public/pw_chrono_threadx/system_clock_config.h
index 3e8a676..6ab829a 100644
--- a/pw_chrono_threadx/public/pw_chrono_threadx/system_clock_config.h
+++ b/pw_chrono_threadx/public/pw_chrono_threadx/system_clock_config.h
@@ -13,18 +13,20 @@
// the License.
#pragma once
-#include <ratio>
-
-#include "pw_chrono/epoch.h"
#include "pw_chrono_threadx/config.h"
-namespace pw::chrono::backend {
-
// ThreadX does not have an API to determine the tick rate/period, instead
// require the user to specify this through the configuration.
-using SystemClockPeriodSecondsRatio =
- std::ratio<PW_CHRONO_THREADX_CFG_CLOCK_PERIOD_SECONDS_NUMERATOR,
- PW_CHRONO_THREADX_CFG_CLOCK_PERIOD_SECONDS_DENOMINATOR>;
+#define PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_NUMERATOR \
+ PW_CHRONO_THREADX_CFG_CLOCK_PERIOD_SECONDS_NUMERATOR
+#define PW_CHRONO_SYSTEM_CLOCK_PERIOD_SECONDS_DENOMINATOR \
+ PW_CHRONO_THREADX_CFG_CLOCK_PERIOD_SECONDS_DENOMINATOR
+
+#ifdef __cplusplus
+
+#include "pw_chrono/epoch.h"
+
+namespace pw::chrono::backend {
// The ThreadX clock starts at zero during initialization, approximately the
// time since boot.
@@ -37,3 +39,5 @@
constexpr inline bool kSystemClockFreeRunning = false;
} // namespace pw::chrono::backend
+
+#endif // __cplusplus
diff --git a/pw_sync/binary_semaphore.cc b/pw_sync/binary_semaphore.cc
index 439504b..5500964 100644
--- a/pw_sync/binary_semaphore.cc
+++ b/pw_sync/binary_semaphore.cc
@@ -33,15 +33,15 @@
extern "C" bool pw_sync_BinarySemaphore_TryAcquireFor(
pw_sync_BinarySemaphore* semaphore,
- pw_chrono_SystemClock_TickCount for_at_least) {
- return semaphore->try_acquire_for(SystemClock::duration(for_at_least));
+ pw_chrono_SystemClock_Duration for_at_least) {
+ return semaphore->try_acquire_for(SystemClock::duration(for_at_least.ticks));
}
extern "C" bool pw_sync_BinarySemaphore_TryAcquireUntil(
pw_sync_BinarySemaphore* semaphore,
pw_chrono_SystemClock_TimePoint until_at_least) {
return semaphore->try_acquire_until(SystemClock::time_point(
- SystemClock::duration(until_at_least.ticks_since_epoch)));
+ SystemClock::duration(until_at_least.duration_since_epoch.ticks)));
}
extern "C" ptrdiff_t pw_sync_BinarySemaphore_Max(void) {
diff --git a/pw_sync/binary_semaphore_facade_test.cc b/pw_sync/binary_semaphore_facade_test.cc
index 7c2273c..d5ad28c 100644
--- a/pw_sync/binary_semaphore_facade_test.cc
+++ b/pw_sync/binary_semaphore_facade_test.cc
@@ -19,6 +19,7 @@
#include "pw_sync/binary_semaphore.h"
using pw::chrono::SystemClock;
+using namespace std::chrono_literals;
namespace pw::sync {
namespace {
@@ -32,7 +33,7 @@
bool pw_sync_BinarySemaphore_CallTryAcquire(pw_sync_BinarySemaphore* semaphore);
bool pw_sync_BinarySemaphore_CallTryAcquireFor(
pw_sync_BinarySemaphore* semaphore,
- pw_chrono_SystemClock_TickCount for_at_least);
+ pw_chrono_SystemClock_Duration for_at_least);
bool pw_sync_BinarySemaphore_CallTryAcquireUntil(
pw_sync_BinarySemaphore* semaphore,
pw_chrono_SystemClock_TimePoint until_at_least);
@@ -40,14 +41,13 @@
} // extern "C"
-static constexpr auto kArbitraryDuration = std::chrono::milliseconds(42);
// We can't control the SystemClock's period configuration, so just in case
// duration cannot be accurately expressed in integer ticks, round the
-// duration w/ duration_cast.
-static constexpr auto kRoundedArbitraryDuration =
- std::chrono::duration_cast<SystemClock::duration>(kArbitraryDuration);
-static constexpr pw_chrono_SystemClock_TickCount kRoundedArbitraryDurationInC =
- kRoundedArbitraryDuration.count();
+// duration w/ ceil.
+constexpr auto kRoundedArbitraryDuration =
+ std::chrono::ceil<SystemClock::duration>(42ms);
+constexpr pw_chrono_SystemClock_Duration kRoundedArbitraryDurationInC =
+ PW_SYSTEM_CLOCK_MS(42);
TEST(BinarySemaphore, EmptyInitialState) {
BinarySemaphore semaphore;
@@ -130,17 +130,17 @@
pw_chrono_SystemClock_TimePoint before = pw_chrono_SystemClock_Now();
ASSERT_TRUE(pw_sync_BinarySemaphore_CallTryAcquireFor(
&semaphore, kRoundedArbitraryDurationInC));
- pw_chrono_SystemClock_TickCount time_elapsed =
- pw_chrono_SystemClock_Now().ticks_since_epoch - before.ticks_since_epoch;
- EXPECT_LT(time_elapsed, kRoundedArbitraryDurationInC);
+ pw_chrono_SystemClock_Duration time_elapsed =
+ pw_chrono_SystemClock_TimeElapsed(before, pw_chrono_SystemClock_Now());
+ EXPECT_LT(time_elapsed.ticks, kRoundedArbitraryDurationInC.ticks);
// Ensure it blocks and fails when empty.
before = pw_chrono_SystemClock_Now();
EXPECT_FALSE(pw_sync_BinarySemaphore_CallTryAcquireFor(
&semaphore, kRoundedArbitraryDurationInC));
time_elapsed =
- pw_chrono_SystemClock_Now().ticks_since_epoch - before.ticks_since_epoch;
- EXPECT_GE(time_elapsed, kRoundedArbitraryDurationInC);
+ pw_chrono_SystemClock_TimeElapsed(before, pw_chrono_SystemClock_Now());
+ EXPECT_GE(time_elapsed.ticks, kRoundedArbitraryDurationInC.ticks);
}
TEST(BinarySemaphore, TryAcquireUntilInC) {
@@ -148,18 +148,20 @@
pw_sync_BinarySemaphore_CallRelease(&semaphore);
pw_chrono_SystemClock_TimePoint deadline;
- deadline.ticks_since_epoch = pw_chrono_SystemClock_Now().ticks_since_epoch +
- kRoundedArbitraryDurationInC;
+ deadline.duration_since_epoch = {
+ .ticks = pw_chrono_SystemClock_Now().duration_since_epoch.ticks +
+ kRoundedArbitraryDurationInC.ticks,
+ };
ASSERT_TRUE(
pw_sync_BinarySemaphore_CallTryAcquireUntil(&semaphore, deadline));
- EXPECT_LT(pw_chrono_SystemClock_Now().ticks_since_epoch,
- deadline.ticks_since_epoch);
+ EXPECT_LT(pw_chrono_SystemClock_Now().duration_since_epoch.ticks,
+ deadline.duration_since_epoch.ticks);
// Ensure it blocks and fails when empty.
EXPECT_FALSE(
pw_sync_BinarySemaphore_CallTryAcquireUntil(&semaphore, deadline));
- EXPECT_GE(pw_chrono_SystemClock_Now().ticks_since_epoch,
- deadline.ticks_since_epoch);
+ EXPECT_GE(pw_chrono_SystemClock_Now().duration_since_epoch.ticks,
+ deadline.duration_since_epoch.ticks);
}
TEST(BinarySemaphore, MaxInC) {
diff --git a/pw_sync/binary_semaphore_facade_test_c.c b/pw_sync/binary_semaphore_facade_test_c.c
index 5145301..22dc7f6 100644
--- a/pw_sync/binary_semaphore_facade_test_c.c
+++ b/pw_sync/binary_semaphore_facade_test_c.c
@@ -34,7 +34,7 @@
bool pw_sync_BinarySemaphore_CallTryAcquireFor(
pw_sync_BinarySemaphore* semaphore,
- pw_chrono_SystemClock_TickCount for_at_least) {
+ pw_chrono_SystemClock_Duration for_at_least) {
return pw_sync_BinarySemaphore_TryAcquireFor(semaphore, for_at_least);
}
diff --git a/pw_sync/counting_semaphore.cc b/pw_sync/counting_semaphore.cc
index 9915e5e..1b7ad3f 100644
--- a/pw_sync/counting_semaphore.cc
+++ b/pw_sync/counting_semaphore.cc
@@ -38,15 +38,15 @@
extern "C" bool pw_sync_CountingSemaphore_TryAcquireFor(
pw_sync_CountingSemaphore* semaphore,
- pw_chrono_SystemClock_TickCount for_at_least) {
- return semaphore->try_acquire_for(SystemClock::duration(for_at_least));
+ pw_chrono_SystemClock_Duration for_at_least) {
+ return semaphore->try_acquire_for(SystemClock::duration(for_at_least.ticks));
}
extern "C" bool pw_sync_CountingSemaphore_TryAcquireUntil(
pw_sync_CountingSemaphore* semaphore,
pw_chrono_SystemClock_TimePoint until_at_least) {
return semaphore->try_acquire_until(SystemClock::time_point(
- SystemClock::duration(until_at_least.ticks_since_epoch)));
+ SystemClock::duration(until_at_least.duration_since_epoch.ticks)));
}
extern "C" ptrdiff_t pw_sync_CountingSemaphore_Max(void) {
diff --git a/pw_sync/counting_semaphore_facade_test.cc b/pw_sync/counting_semaphore_facade_test.cc
index 3d5b331..b0f1bc8 100644
--- a/pw_sync/counting_semaphore_facade_test.cc
+++ b/pw_sync/counting_semaphore_facade_test.cc
@@ -19,6 +19,7 @@
#include "pw_sync/counting_semaphore.h"
using pw::chrono::SystemClock;
+using namespace std::chrono_literals;
namespace pw::sync {
namespace {
@@ -37,7 +38,7 @@
pw_sync_CountingSemaphore* semaphore);
bool pw_sync_CountingSemaphore_CallTryAcquireFor(
pw_sync_CountingSemaphore* semaphore,
- pw_chrono_SystemClock_TickCount for_at_least);
+ pw_chrono_SystemClock_Duration for_at_least);
bool pw_sync_CountingSemaphore_CallTryAcquireUntil(
pw_sync_CountingSemaphore* semaphore,
pw_chrono_SystemClock_TimePoint until_at_least);
@@ -45,14 +46,13 @@
} // extern "C"
-static constexpr auto kArbitraryDuration = std::chrono::milliseconds(42);
// We can't control the SystemClock's period configuration, so just in case
// duration cannot be accurately expressed in integer ticks, round the
-// duration w/ duration_cast.
-static constexpr auto kRoundedArbitraryDuration =
- std::chrono::duration_cast<SystemClock::duration>(kArbitraryDuration);
-static constexpr pw_chrono_SystemClock_TickCount kRoundedArbitraryDurationInC =
- kRoundedArbitraryDuration.count();
+// duration w/ ceil.
+constexpr auto kRoundedArbitraryDuration =
+ std::chrono::ceil<SystemClock::duration>(42ms);
+constexpr pw_chrono_SystemClock_Duration kRoundedArbitraryDurationInC =
+ PW_SYSTEM_CLOCK_MS(42);
TEST(CountingSemaphore, EmptyInitialState) {
CountingSemaphore semaphore;
@@ -160,17 +160,17 @@
pw_chrono_SystemClock_TimePoint before = pw_chrono_SystemClock_Now();
ASSERT_TRUE(pw_sync_CountingSemaphore_CallTryAcquireFor(
&semaphore, kRoundedArbitraryDurationInC));
- pw_chrono_SystemClock_TickCount time_elapsed =
- pw_chrono_SystemClock_Now().ticks_since_epoch - before.ticks_since_epoch;
- EXPECT_LT(time_elapsed, kRoundedArbitraryDurationInC);
+ pw_chrono_SystemClock_Duration time_elapsed =
+ pw_chrono_SystemClock_TimeElapsed(before, pw_chrono_SystemClock_Now());
+ EXPECT_LT(time_elapsed.ticks, kRoundedArbitraryDurationInC.ticks);
// Ensure it blocks and fails when empty.
before = pw_chrono_SystemClock_Now();
EXPECT_FALSE(pw_sync_CountingSemaphore_CallTryAcquireFor(
&semaphore, kRoundedArbitraryDurationInC));
time_elapsed =
- pw_chrono_SystemClock_Now().ticks_since_epoch - before.ticks_since_epoch;
- EXPECT_GE(time_elapsed, kRoundedArbitraryDurationInC);
+ pw_chrono_SystemClock_TimeElapsed(before, pw_chrono_SystemClock_Now());
+ EXPECT_GE(time_elapsed.ticks, kRoundedArbitraryDurationInC.ticks);
}
TEST(CountingSemaphore, TryAcquireUntilInC) {
@@ -178,18 +178,20 @@
pw_sync_CountingSemaphore_CallRelease(&semaphore);
pw_chrono_SystemClock_TimePoint deadline;
- deadline.ticks_since_epoch = pw_chrono_SystemClock_Now().ticks_since_epoch +
- kRoundedArbitraryDurationInC;
+ deadline.duration_since_epoch = {
+ .ticks = pw_chrono_SystemClock_Now().duration_since_epoch.ticks +
+ kRoundedArbitraryDurationInC.ticks,
+ };
ASSERT_TRUE(
pw_sync_CountingSemaphore_CallTryAcquireUntil(&semaphore, deadline));
- EXPECT_LT(pw_chrono_SystemClock_Now().ticks_since_epoch,
- deadline.ticks_since_epoch);
+ EXPECT_LT(pw_chrono_SystemClock_Now().duration_since_epoch.ticks,
+ deadline.duration_since_epoch.ticks);
// Ensure it blocks and fails when empty.
EXPECT_FALSE(
pw_sync_CountingSemaphore_CallTryAcquireUntil(&semaphore, deadline));
- EXPECT_GE(pw_chrono_SystemClock_Now().ticks_since_epoch,
- deadline.ticks_since_epoch);
+ EXPECT_GE(pw_chrono_SystemClock_Now().duration_since_epoch.ticks,
+ deadline.duration_since_epoch.ticks);
}
TEST(CountingSemaphore, MaxInC) {
diff --git a/pw_sync/counting_semaphore_facade_test_c.c b/pw_sync/counting_semaphore_facade_test_c.c
index 592df9b..93db6d1 100644
--- a/pw_sync/counting_semaphore_facade_test_c.c
+++ b/pw_sync/counting_semaphore_facade_test_c.c
@@ -41,7 +41,7 @@
bool pw_sync_CountingSemaphore_CallTryAcquireFor(
pw_sync_CountingSemaphore* semaphore,
- pw_chrono_SystemClock_TickCount for_at_least) {
+ pw_chrono_SystemClock_Duration for_at_least) {
return pw_sync_CountingSemaphore_TryAcquireFor(semaphore, for_at_least);
}
diff --git a/pw_sync/mutex.cc b/pw_sync/mutex.cc
index 85c3c92..416182e 100644
--- a/pw_sync/mutex.cc
+++ b/pw_sync/mutex.cc
@@ -23,13 +23,13 @@
}
extern "C" bool pw_sync_Mutex_TryLockFor(
- pw_sync_Mutex* mutex, pw_chrono_SystemClock_TickCount for_at_least) {
- return mutex->try_lock_for(SystemClock::duration(for_at_least));
+ pw_sync_Mutex* mutex, pw_chrono_SystemClock_Duration for_at_least) {
+ return mutex->try_lock_for(SystemClock::duration(for_at_least.ticks));
}
extern "C" bool pw_sync_Mutex_TryLockUntil(
pw_sync_Mutex* mutex, pw_chrono_SystemClock_TimePoint until_at_least) {
return mutex->try_lock_until(SystemClock::time_point(
- SystemClock::duration(until_at_least.ticks_since_epoch)));
+ SystemClock::duration(until_at_least.duration_since_epoch.ticks)));
}
extern "C" void pw_sync_Mutex_Unlock(pw_sync_Mutex* mutex) { mutex->unlock(); }
diff --git a/pw_sync/mutex_facade_test.cc b/pw_sync/mutex_facade_test.cc
index 9cc5bf3..30cef1f 100644
--- a/pw_sync/mutex_facade_test.cc
+++ b/pw_sync/mutex_facade_test.cc
@@ -19,6 +19,7 @@
#include "pw_sync/mutex.h"
using pw::chrono::SystemClock;
+using namespace std::chrono_literals;
namespace pw::sync {
namespace {
@@ -29,21 +30,20 @@
void pw_sync_Mutex_CallLock(pw_sync_Mutex* mutex);
bool pw_sync_Mutex_CallTryLock(pw_sync_Mutex* mutex);
bool pw_sync_Mutex_CallTryLockFor(pw_sync_Mutex* mutex,
- pw_chrono_SystemClock_TickCount for_at_least);
+ pw_chrono_SystemClock_Duration for_at_least);
bool pw_sync_Mutex_CallTryLockUntil(
pw_sync_Mutex* mutex, pw_chrono_SystemClock_TimePoint until_at_least);
void pw_sync_Mutex_CallUnlock(pw_sync_Mutex* mutex);
} // extern "C"
-static constexpr auto kArbitraryDuration = std::chrono::milliseconds(42);
// We can't control the SystemClock's period configuration, so just in case
// duration cannot be accurately expressed in integer ticks, round the
-// duration w/ duration_cast.
-static constexpr auto kRoundedArbitraryDuration =
- std::chrono::duration_cast<SystemClock::duration>(kArbitraryDuration);
-static constexpr pw_chrono_SystemClock_TickCount kRoundedArbitraryDurationInC =
- kRoundedArbitraryDuration.count();
+// duration w/ ceil.
+constexpr auto kRoundedArbitraryDuration =
+ std::chrono::ceil<SystemClock::duration>(42ms);
+constexpr pw_chrono_SystemClock_Duration kRoundedArbitraryDurationInC =
+ PW_SYSTEM_CLOCK_MS(42);
// TODO(pwbug/291): Add real concurrency tests once we have pw::thread.
@@ -124,18 +124,17 @@
pw_chrono_SystemClock_TimePoint before = pw_chrono_SystemClock_Now();
ASSERT_TRUE(
pw_sync_Mutex_CallTryLockFor(&mutex, kRoundedArbitraryDurationInC));
- pw_chrono_SystemClock_TickCount time_elapsed =
- pw_chrono_SystemClock_Now().ticks_since_epoch - before.ticks_since_epoch;
- EXPECT_LT(time_elapsed, kRoundedArbitraryDurationInC);
+ pw_chrono_SystemClock_Duration time_elapsed =
+ pw_chrono_SystemClock_TimeElapsed(before, pw_chrono_SystemClock_Now());
+ EXPECT_LT(time_elapsed.ticks, kRoundedArbitraryDurationInC.ticks);
// TODO(pwbug/291): Ensure it blocks fails to lock when already held.
// before = pw_chrono_SystemClock_Now();
// EXPECT_FALSE(
// pw_sync_Mutex_CallTryLockFor(&mutex, kRoundedArbitraryDurationInC));
// time_elapsed =
- // pw_chrono_SystemClock_Now().ticks_since_epoch -
- // before.ticks_since_epoch;
- // EXPECT_GE(time_elapsed, kRoundedArbitraryDurationInC);
+ // pw_chrono_SystemClock_TimeElapsed(before, pw_chrono_SystemClock_Now());
+ // EXPECT_GE(time_elapsed.ticks, kRoundedArbitraryDurationInC.ticks);
pw_sync_Mutex_CallUnlock(&mutex);
}
@@ -143,16 +142,17 @@
TEST(Mutex, TryLockUnlockUntilInC) {
pw::sync::Mutex mutex;
pw_chrono_SystemClock_TimePoint deadline;
- deadline.ticks_since_epoch = pw_chrono_SystemClock_Now().ticks_since_epoch +
- kRoundedArbitraryDurationInC;
+ deadline.duration_since_epoch.ticks =
+ pw_chrono_SystemClock_Now().duration_since_epoch.ticks +
+ kRoundedArbitraryDurationInC.ticks;
ASSERT_TRUE(pw_sync_Mutex_CallTryLockUntil(&mutex, deadline));
- EXPECT_LT(pw_chrono_SystemClock_Now().ticks_since_epoch,
- deadline.ticks_since_epoch);
+ EXPECT_LT(pw_chrono_SystemClock_Now().duration_since_epoch.ticks,
+ deadline.duration_since_epoch.ticks);
// TODO(pwbug/291): Ensure it blocks fails to lock when already held.
// EXPECT_FALSE(pw_sync_Mutex_CallTryLockUntil(&mutex, deadline));
- // EXPECT_GE(pw_chrono_SystemClock_Now().ticks_since_epoch,
- // deadline.ticks_since_epoch);
+ // EXPECT_GE(pw_chrono_SystemClock_Now().duration_since_epoch.ticks,
+ // deadline.duration_since_epoch.ticks);
mutex.unlock();
}
diff --git a/pw_sync/mutex_facade_test_c.c b/pw_sync/mutex_facade_test_c.c
index 9004912..5b1e631 100644
--- a/pw_sync/mutex_facade_test_c.c
+++ b/pw_sync/mutex_facade_test_c.c
@@ -25,8 +25,8 @@
return pw_sync_Mutex_TryLock(mutex);
}
-bool pw_sync_Mutex_CallTryLockFor(
- pw_sync_Mutex* mutex, pw_chrono_SystemClock_TickCount for_at_least) {
+bool pw_sync_Mutex_CallTryLockFor(pw_sync_Mutex* mutex,
+ pw_chrono_SystemClock_Duration for_at_least) {
return pw_sync_Mutex_TryLockFor(mutex, for_at_least);
}
diff --git a/pw_sync/public/pw_sync/binary_semaphore.h b/pw_sync/public/pw_sync/binary_semaphore.h
index 4886b34..43603ec 100644
--- a/pw_sync/public/pw_sync/binary_semaphore.h
+++ b/pw_sync/public/pw_sync/binary_semaphore.h
@@ -109,7 +109,7 @@
bool pw_sync_BinarySemaphore_TryAcquire(pw_sync_BinarySemaphore* semaphore);
bool pw_sync_BinarySemaphore_TryAcquireFor(
pw_sync_BinarySemaphore* semaphore,
- pw_chrono_SystemClock_TickCount for_at_least);
+ pw_chrono_SystemClock_Duration for_at_least);
bool pw_sync_BinarySemaphore_TryAcquireUntil(
pw_sync_BinarySemaphore* semaphore,
pw_chrono_SystemClock_TimePoint until_at_least);
diff --git a/pw_sync/public/pw_sync/counting_semaphore.h b/pw_sync/public/pw_sync/counting_semaphore.h
index a7b94f6..8768bab 100644
--- a/pw_sync/public/pw_sync/counting_semaphore.h
+++ b/pw_sync/public/pw_sync/counting_semaphore.h
@@ -111,7 +111,7 @@
bool pw_sync_CountingSemaphore_TryAcquire(pw_sync_CountingSemaphore* semaphore);
bool pw_sync_CountingSemaphore_TryAcquireFor(
pw_sync_CountingSemaphore* semaphore,
- pw_chrono_SystemClock_TickCount for_at_least);
+ pw_chrono_SystemClock_Duration for_at_least);
bool pw_sync_CountingSemaphore_TryAcquireUntil(
pw_sync_CountingSemaphore* semaphore,
pw_chrono_SystemClock_TimePoint until_at_least);
diff --git a/pw_sync/public/pw_sync/mutex.h b/pw_sync/public/pw_sync/mutex.h
index 3030c09..1bc77d7 100644
--- a/pw_sync/public/pw_sync/mutex.h
+++ b/pw_sync/public/pw_sync/mutex.h
@@ -109,7 +109,7 @@
void pw_sync_Mutex_Lock(pw_sync_Mutex* mutex);
bool pw_sync_Mutex_TryLock(pw_sync_Mutex* mutex);
bool pw_sync_Mutex_TryLockFor(pw_sync_Mutex* mutex,
- pw_chrono_SystemClock_TickCount for_at_least);
+ pw_chrono_SystemClock_Duration for_at_least);
bool pw_sync_Mutex_TryLockUntil(pw_sync_Mutex* mutex,
pw_chrono_SystemClock_TimePoint until_at_least);
void pw_sync_Mutex_Unlock(pw_sync_Mutex* mutex);
diff --git a/pw_thread/public/pw_thread/sleep.h b/pw_thread/public/pw_thread/sleep.h
index 4deb472..93e8320 100644
--- a/pw_thread/public/pw_thread/sleep.h
+++ b/pw_thread/public/pw_thread/sleep.h
@@ -37,7 +37,7 @@
PW_EXTERN_C_START
-void pw_this_thread_SleepFor(pw_chrono_SystemClock_TickCount for_at_least);
+void pw_this_thread_SleepFor(pw_chrono_SystemClock_Duration for_at_least);
void pw_this_thread_SleepUntil(pw_chrono_SystemClock_TimePoint until_at_least);
PW_EXTERN_C_END
diff --git a/pw_thread/sleep.cc b/pw_thread/sleep.cc
index 28313fd..403df3a 100644
--- a/pw_thread/sleep.cc
+++ b/pw_thread/sleep.cc
@@ -17,12 +17,12 @@
using pw::chrono::SystemClock;
extern "C" void pw_this_thread_SleepFor(
- pw_chrono_SystemClock_TickCount for_at_least) {
- pw::this_thread::sleep_for(SystemClock::duration(for_at_least));
+ pw_chrono_SystemClock_Duration for_at_least) {
+ pw::this_thread::sleep_for(SystemClock::duration(for_at_least.ticks));
}
extern "C" void pw_this_thread_SleepUntil(
pw_chrono_SystemClock_TimePoint until_at_least) {
pw::this_thread::sleep_until(SystemClock::time_point(
- SystemClock::duration(until_at_least.ticks_since_epoch)));
+ SystemClock::duration(until_at_least.duration_since_epoch.ticks)));
}
diff --git a/pw_thread/sleep_facade_test.cc b/pw_thread/sleep_facade_test.cc
index 5956720..42548bd 100644
--- a/pw_thread/sleep_facade_test.cc
+++ b/pw_thread/sleep_facade_test.cc
@@ -20,6 +20,7 @@
#include "pw_thread/sleep.h"
using pw::chrono::SystemClock;
+using namespace std::chrono_literals;
namespace pw::this_thread {
namespace {
@@ -27,20 +28,19 @@
extern "C" {
// Functions defined in sleep_facade_test_c.c which call the API from C.
-void pw_this_thread_CallSleepFor(pw_chrono_SystemClock_TickCount for_at_least);
+void pw_this_thread_CallSleepFor(pw_chrono_SystemClock_Duration for_at_least);
void pw_this_thread_CallSleepUntil(
pw_chrono_SystemClock_TimePoint until_at_least);
} // extern "C"
-static constexpr auto kArbitraryDuration = std::chrono::milliseconds(42);
// We can't control the SystemClock's period configuration, so just in case
// duration cannot be accurately expressed in integer ticks, round the
-// duration w/ duration_cast.
-static constexpr auto kRoundedArbitraryDuration =
- std::chrono::duration_cast<SystemClock::duration>(kArbitraryDuration);
-static constexpr pw_chrono_SystemClock_TickCount kRoundedArbitraryDurationInC =
- kRoundedArbitraryDuration.count();
+// duration w/ ceil.
+constexpr auto kRoundedArbitraryDuration =
+ std::chrono::ceil<SystemClock::duration>(42ms);
+constexpr pw_chrono_SystemClock_Duration kRoundedArbitraryDurationInC =
+ PW_SYSTEM_CLOCK_MS(42);
TEST(Sleep, SleepFor) {
// Ensure we are in a thread context, meaning we are permitted to sleep.
@@ -68,9 +68,9 @@
pw_chrono_SystemClock_TimePoint before = pw_chrono_SystemClock_Now();
pw_this_thread_SleepFor(kRoundedArbitraryDurationInC);
- pw_chrono_SystemClock_TickCount time_elapsed =
- pw_chrono_SystemClock_Now().ticks_since_epoch - before.ticks_since_epoch;
- EXPECT_GE(time_elapsed, kRoundedArbitraryDurationInC);
+ pw_chrono_SystemClock_Duration time_elapsed =
+ pw_chrono_SystemClock_TimeElapsed(before, pw_chrono_SystemClock_Now());
+ EXPECT_GE(time_elapsed.ticks, kRoundedArbitraryDurationInC.ticks);
}
TEST(Sleep, SleepUntilInC) {
@@ -78,11 +78,12 @@
ASSERT_NE(get_id(), thread::Id());
pw_chrono_SystemClock_TimePoint deadline;
- deadline.ticks_since_epoch = pw_chrono_SystemClock_Now().ticks_since_epoch +
- kRoundedArbitraryDurationInC;
+ deadline.duration_since_epoch.ticks =
+ pw_chrono_SystemClock_Now().duration_since_epoch.ticks +
+ kRoundedArbitraryDurationInC.ticks;
pw_this_thread_CallSleepUntil(deadline);
- EXPECT_GE(pw_chrono_SystemClock_Now().ticks_since_epoch,
- deadline.ticks_since_epoch);
+ EXPECT_GE(pw_chrono_SystemClock_Now().duration_since_epoch.ticks,
+ deadline.duration_since_epoch.ticks);
}
} // namespace
diff --git a/pw_thread/sleep_facade_test_c.c b/pw_thread/sleep_facade_test_c.c
index c2f536e..450c387 100644
--- a/pw_thread/sleep_facade_test_c.c
+++ b/pw_thread/sleep_facade_test_c.c
@@ -17,7 +17,7 @@
#include "pw_thread/sleep.h"
-void pw_this_thread_CallSleepFor(pw_chrono_SystemClock_TickCount for_at_least) {
+void pw_this_thread_CallSleepFor(pw_chrono_SystemClock_Duration for_at_least) {
pw_this_thread_SleepFor(for_at_least);
}
diff --git a/pw_trace/example/sample_app.cc b/pw_trace/example/sample_app.cc
index c0fd0ea..8edefa9 100644
--- a/pw_trace/example/sample_app.cc
+++ b/pw_trace/example/sample_app.cc
@@ -38,7 +38,7 @@
auto start = system_clock::now();
uint32_t GetTimeSinceBootMillis() {
auto delta = system_clock::now() - start;
- return duration_cast<milliseconds>(delta).count();
+ return floor<milliseconds>(delta).count();
}
// Creating a very simple runnable with predictable behaviour to help with the
@@ -208,4 +208,4 @@
} // namespace
-void RunTraceSampleApp() { StartFakeKernel(); }
\ No newline at end of file
+void RunTraceSampleApp() { StartFakeKernel(); }
diff --git a/pw_trace_tokenized/host_trace_time.cc b/pw_trace_tokenized/host_trace_time.cc
index ed004dc..ce60880 100644
--- a/pw_trace_tokenized/host_trace_time.cc
+++ b/pw_trace_tokenized/host_trace_time.cc
@@ -29,7 +29,7 @@
// Define trace time as a counter for tests.
PW_TRACE_TIME_TYPE pw_trace_GetTraceTime() {
auto delta = steady_clock::now() - start;
- return duration_cast<microseconds>(delta).count();
+ return floor<microseconds>(delta).count();
}
// Microsecond time source