From 13013397bec33c7ec76c6899664aef7c7c181ddf Mon Sep 17 00:00:00 2001 From: Pascal Brunot Date: Sun, 14 Jul 2024 14:37:36 +0200 Subject: [PATCH] Tasks: using std::chrono ::steady_clock::time_point instead of millis --- .github/workflows/tests.yml | 1 + include/Machine.hpp | 4 +- include/Tasks.hpp | 18 ++++----- include/mock/MockMrfc522.hpp | 2 +- src/Machine.cpp | 5 ++- src/Tasks.cpp | 18 ++++----- test/test_chrono/test_chrono.cpp | 66 ++++++++++++++++++++++++++++++++ 7 files changed, 92 insertions(+), 22 deletions(-) create mode 100644 test/test_chrono/test_chrono.cpp diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 033bd0ec..bcf1bf5b 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -26,6 +26,7 @@ jobs: - test_logic - test_savedconfig - test_tasks + - test_chrono steps: - uses: actions/checkout@v4 with: diff --git a/include/Machine.hpp b/include/Machine.hpp index f1424334..c59b767e 100644 --- a/include/Machine.hpp +++ b/include/Machine.hpp @@ -107,8 +107,8 @@ namespace fabomatic bool active{false}; FabUser current_user{}; - std::optional usage_start_timestamp{std::nullopt}; // When did the machine start? - std::optional logoff_timestamp{std::nullopt}; // When did the last user log off? + std::optional usage_start_timestamp{std::nullopt}; // When did the machine start? + std::optional logoff_timestamp{std::nullopt}; // When did the last user log off? PowerState power_state{PowerState::PoweredOff}; /// @brief If true, machine needs maintenance diff --git a/include/Tasks.hpp b/include/Tasks.hpp index 35caf168..6bb9309b 100644 --- a/include/Tasks.hpp +++ b/include/Tasks.hpp @@ -12,9 +12,9 @@ namespace fabomatic::Tasks using milliseconds = std::chrono::milliseconds; using namespace std::chrono_literals; - [[nodiscard]] inline auto arduinoNow() -> milliseconds + [[nodiscard]] inline auto arduinoNow() -> const std::chrono::steady_clock::time_point { - return milliseconds{::millis()}; + return std::chrono::steady_clock::now(); } class Scheduler; @@ -69,7 +69,7 @@ namespace fabomatic::Tasks [[nodiscard]] auto isActive() const -> bool; /// @brief Current period of the task - [[nodiscard]] auto getPeriod() const -> milliseconds; + [[nodiscard]] auto getPeriod() const -> const milliseconds; /// @brief Function to be called when task is run /// @return Callback function @@ -80,20 +80,20 @@ namespace fabomatic::Tasks /// @brief Get the initial delay before the task is run at given period /// @return Delay in milliseconds - [[nodiscard]] auto getDelay() const -> milliseconds; + [[nodiscard]] auto getDelay() const -> const milliseconds; /// @brief Get the average tardiness, i.e. the average period between scheduled start and actual start of execution. - [[nodiscard]] auto getAvgTardiness() const -> milliseconds; + [[nodiscard]] auto getAvgTardiness() const -> const milliseconds; /// @brief Gets the number of times the task has been run. [[nodiscard]] auto getRunCounter() const -> unsigned long; /// @brief Gets the total execution time of the task. Useful to spot slowest tasks - [[nodiscard]] auto getTotalRuntime() const -> milliseconds; + [[nodiscard]] auto getTotalRuntime() const -> const milliseconds; /// @brief When shall the task be run again /// @return time_point of the next run or time_point::max() if the task will not run. - [[nodiscard]] auto getNextRun() const -> milliseconds; + [[nodiscard]] auto getNextRun() const -> const std::chrono::steady_clock::time_point; [[nodiscard]] auto toString() const -> const std::string; @@ -102,8 +102,8 @@ namespace fabomatic::Tasks const std::string id; milliseconds period; milliseconds delay; - milliseconds last_run; - milliseconds next_run; + std::chrono::steady_clock::time_point last_run; + std::chrono::steady_clock::time_point next_run; milliseconds average_tardiness; milliseconds total_runtime; std::function callback; diff --git a/include/mock/MockMrfc522.hpp b/include/mock/MockMrfc522.hpp index 1cc8866a..7b8d030e 100644 --- a/include/mock/MockMrfc522.hpp +++ b/include/mock/MockMrfc522.hpp @@ -19,7 +19,7 @@ namespace fabomatic { private: std::optional uid{std::nullopt}; - std::optional stop_uid_simulate_time{std::nullopt}; + std::optional stop_uid_simulate_time{std::nullopt}; std::optional getSimulatedUid() const; public: diff --git a/src/Machine.cpp b/src/Machine.cpp index 9383e07b..f88c7359 100644 --- a/src/Machine.cpp +++ b/src/Machine.cpp @@ -260,7 +260,10 @@ namespace fabomatic sstream << ", MaintenanceNeeded:" << maintenanceNeeded; sstream << ", " << config.value().toString(); sstream << ", Active:" << active; - sstream << ", Last logoff:" << (logoff_timestamp.has_value() ? logoff_timestamp.value().count() : 0); + if (logoff_timestamp) + { + sstream << ", Last logoff:" << logoff_timestamp.value().time_since_epoch(); + } sstream << ", GracePeriod (s):" << getGracePeriod().count(); sstream << ")"; diff --git a/src/Tasks.cpp b/src/Tasks.cpp index c30154b0..93f90213 100644 --- a/src/Tasks.cpp +++ b/src/Tasks.cpp @@ -140,8 +140,8 @@ namespace fabomatic::Tasks std::stringstream ss; ss << "Task " << getId() << ", active=" << active << ",Period=" << period << ", Delay=" << delay - << ",Last run=" << last_run.count() - << ",Next_run=" << next_run.count() + << ",Last run=" << last_run.time_since_epoch() + << ",Next_run=" << next_run.time_since_epoch() << ",Avg tardiness=" << average_tardiness << ",total_runtime " << total_runtime << ",run_counter=" << run_counter @@ -155,8 +155,8 @@ namespace fabomatic::Tasks if (isActive() && time_to_run) { run_counter++; - auto last_period = arduinoNow() - last_run; - average_tardiness = (average_tardiness * (run_counter - 1) + last_period) / run_counter; + auto last_duration = std::chrono::duration_cast(arduinoNow() - last_run); + average_tardiness = (average_tardiness * (run_counter - 1) + last_duration) / run_counter; last_run = arduinoNow(); callback(); @@ -212,7 +212,7 @@ namespace fabomatic::Tasks return active; } - auto Task::getPeriod() const -> milliseconds + auto Task::getPeriod() const -> const milliseconds { return period; } @@ -227,7 +227,7 @@ namespace fabomatic::Tasks return id; } - auto Task::getAvgTardiness() const -> milliseconds + auto Task::getAvgTardiness() const -> const milliseconds { if (average_tardiness > period) { @@ -241,7 +241,7 @@ namespace fabomatic::Tasks return run_counter; } - auto Task::getDelay() const -> milliseconds + auto Task::getDelay() const -> const milliseconds { return delay; } @@ -251,12 +251,12 @@ namespace fabomatic::Tasks delay = new_delay; } - auto Task::getTotalRuntime() const -> milliseconds + auto Task::getTotalRuntime() const -> const milliseconds { return total_runtime; } - auto Task::getNextRun() const -> milliseconds + auto Task::getNextRun() const -> const std::chrono::steady_clock::time_point { return next_run; } diff --git a/test/test_chrono/test_chrono.cpp b/test/test_chrono/test_chrono.cpp new file mode 100644 index 00000000..bfa455f4 --- /dev/null +++ b/test/test_chrono/test_chrono.cpp @@ -0,0 +1,66 @@ +#include +#include +#include + +#include +#define UNITY_INCLUDE_PRINT_FORMATTED +#include +#include "Tasks.hpp" +#include "Logging.hpp" +#include "Espressif.hpp" + +[[maybe_unused]] static const char *TAG4 = "test_chrono"; + +using namespace std::chrono_literals; + +namespace fabomatic::tests +{ + using Task = fabomatic::Tasks::Task; + using Scheduler = fabomatic::Tasks::Scheduler; + + void tearDown(void) + { + } + + void setUp(void) + { + // set stuff up here + } + + void test_steady_clock(void) + { + static constexpr auto nb_tests = 100; + + auto cpt = 0; + TEST_ASSERT_TRUE_MESSAGE(std::chrono::steady_clock::is_steady, "Steady clock available"); + auto previous_val = std::chrono::steady_clock::now(); + while (cpt < nb_tests) + { + auto val = std::chrono::steady_clock::now(); + auto duration = (val - previous_val); + auto count = duration.count(); + std::stringstream ss{}; + ss << "Duration = " << duration << ", tse=" << val.time_since_epoch(); + auto log = ss.str().c_str(); + ESP_LOGI(TAG4, "%s", log); + TEST_ASSERT_GREATER_THAN_MESSAGE(0, count, "Duration"); + ::delay(10); + previous_val = val; + cpt++; + } + } + +} // namespace fabomatic::tests + +void setup() +{ + delay(1000); + esp_log_level_set(TAG4, LOG_LOCAL_LEVEL); + UNITY_BEGIN(); + RUN_TEST(fabomatic::tests::test_steady_clock); + UNITY_END(); // stop unit testing +} + +void loop() +{ +} \ No newline at end of file