aboutsummaryrefslogtreecommitdiff
path: root/pw_async
diff options
context:
space:
mode:
authorBen <benlawson@google.com>2023-02-02 22:46:21 +0000
committerCQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-02-02 22:46:21 +0000
commit158a376b73c737d1bbc87c07a29919c7b21b5fc2 (patch)
treea316a552abde9e870c552da10807a34ad619145e /pw_async
parentb36042d676773984be76bd3ff8217015688c27b9 (diff)
downloadpigweed-158a376b73c737d1bbc87c07a29919c7b21b5fc2.tar.gz
pw_async: Implement VirtualSystemClock for Dispatchers
Implement VirtualSystemClock in BasicDispatcher and TestDispatcher. Bug: b/254532947 Change-Id: I50861ea67d833d01b7af377b2e739526397ec53c Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/126930 Reviewed-by: Erik Gilling <konkers@google.com> Commit-Queue: Ben Lawson <benlawson@google.com>
Diffstat (limited to 'pw_async')
-rw-r--r--pw_async/BUILD.gn5
-rw-r--r--pw_async/dispatcher_basic.cc16
-rw-r--r--pw_async/dispatcher_test.cc2
-rw-r--r--pw_async/public/pw_async/dispatcher.h13
-rw-r--r--pw_async/public/pw_async/dispatcher_basic.h12
-rw-r--r--pw_async/public_test/pw_async/test_dispatcher.h6
-rw-r--r--pw_async/test_dispatcher.cc10
7 files changed, 37 insertions, 27 deletions
diff --git a/pw_async/BUILD.gn b/pw_async/BUILD.gn
index 42f1dc367..ebed69fd9 100644
--- a/pw_async/BUILD.gn
+++ b/pw_async/BUILD.gn
@@ -41,7 +41,10 @@ pw_source_set("task") {
pw_source_set("dispatcher") {
public_configs = [ ":public_include_path" ]
- public_deps = [ ":task" ]
+ public_deps = [
+ ":task",
+ "$dir_pw_chrono:system_clock",
+ ]
public = [ "public/pw_async/dispatcher.h" ]
visibility = [ ":*" ] + pw_async_EXPERIMENTAL_MODULE_VISIBILITY
}
diff --git a/pw_async/dispatcher_basic.cc b/pw_async/dispatcher_basic.cc
index 03394fec4..2425b11a8 100644
--- a/pw_async/dispatcher_basic.cc
+++ b/pw_async/dispatcher_basic.cc
@@ -39,23 +39,23 @@ void BasicDispatcher::RunUntilIdle() {
void BasicDispatcher::RunUntil(chrono::SystemClock::time_point end_time) {
lock_.lock();
- while (end_time < Now()) {
+ while (end_time < now()) {
RunLoopOnce();
}
lock_.unlock();
}
void BasicDispatcher::RunFor(chrono::SystemClock::duration duration) {
- RunUntil(Now() + duration);
+ RunUntil(now() + duration);
}
void BasicDispatcher::RunLoopOnce() {
- if (task_queue_.empty() || DueTime(task_queue_.front()) > Now()) {
+ if (task_queue_.empty() || DueTime(task_queue_.front()) > now()) {
// Sleep until a notification is received or until the due time of the
// next task. Notifications are sent when tasks are posted or 'stop' is
// requested.
chrono::SystemClock::time_point wake_time =
- task_queue_.empty() ? Now() + SLEEP_DURATION
+ task_queue_.empty() ? now() + SLEEP_DURATION
: DueTime(task_queue_.front());
lock_.unlock();
@@ -66,7 +66,7 @@ void BasicDispatcher::RunLoopOnce() {
return;
}
- while (!task_queue_.empty() && DueTime(task_queue_.front()) <= Now()) {
+ while (!task_queue_.empty() && DueTime(task_queue_.front()) <= now()) {
Task& task = task_queue_.front();
task_queue_.pop_front();
@@ -90,11 +90,11 @@ void BasicDispatcher::RequestStop() {
timed_notification_.release();
}
-void BasicDispatcher::PostTask(Task& task) { PostTaskForTime(task, Now()); }
+void BasicDispatcher::PostTask(Task& task) { PostTaskForTime(task, now()); }
void BasicDispatcher::PostDelayedTask(Task& task,
chrono::SystemClock::duration delay) {
- PostTaskForTime(task, Now() + delay);
+ PostTaskForTime(task, now() + delay);
}
void BasicDispatcher::PostTaskForTime(Task& task,
@@ -107,7 +107,7 @@ void BasicDispatcher::PostTaskForTime(Task& task,
void BasicDispatcher::SchedulePeriodicTask(
Task& task, chrono::SystemClock::duration interval) {
- SchedulePeriodicTask(task, interval, Now());
+ SchedulePeriodicTask(task, interval, now());
}
void BasicDispatcher::SchedulePeriodicTask(
diff --git a/pw_async/dispatcher_test.cc b/pw_async/dispatcher_test.cc
index b37a3aef6..dba072313 100644
--- a/pw_async/dispatcher_test.cc
+++ b/pw_async/dispatcher_test.cc
@@ -141,7 +141,7 @@ TEST(TestDispatcher, PeriodicTasks) {
TestPrimitives tp;
Task periodic_task([&tp]([[maybe_unused]] Context& c) { ++tp.count; });
- dispatcher.SchedulePeriodicTask(periodic_task, 20ms, dispatcher.Now() + 50ms);
+ dispatcher.SchedulePeriodicTask(periodic_task, 20ms, dispatcher.now() + 50ms);
// Cancel periodic task after it has run thrice, at +50ms, +70ms, and +90ms.
Task cancel_task(
diff --git a/pw_async/public/pw_async/dispatcher.h b/pw_async/public/pw_async/dispatcher.h
index df449200f..bdd6e192f 100644
--- a/pw_async/public/pw_async/dispatcher.h
+++ b/pw_async/public/pw_async/dispatcher.h
@@ -14,20 +14,23 @@
#pragma once
#include "pw_async/task.h"
+#include "pw_chrono/system_clock.h"
namespace pw::async {
// Asynchronous Dispatcher abstract class. A default implementation is provided
// in dispatcher_basic.h.
-class Dispatcher {
+//
+// Dispatcher implements VirtualSystemClock so the Dispatcher's time can be
+// injected into other modules under test. This is useful for consistently
+// simulating time when using TestDispatcher (rather than using
+// chrono::SimulatedSystemClock separately).
+class Dispatcher : public chrono::VirtualSystemClock {
public:
- virtual ~Dispatcher() = default;
+ ~Dispatcher() override = default;
virtual void RequestStop() = 0;
- // Returns the current time as viewed by the Dispatcher.
- virtual chrono::SystemClock::time_point Now() = 0;
-
// Post caller owned |task|.
virtual void PostTask(Task& task) = 0;
diff --git a/pw_async/public/pw_async/dispatcher_basic.h b/pw_async/public/pw_async/dispatcher_basic.h
index 482990c20..51efc91b5 100644
--- a/pw_async/public/pw_async/dispatcher_basic.h
+++ b/pw_async/public/pw_async/dispatcher_basic.h
@@ -28,11 +28,6 @@ class BasicDispatcher final : public Dispatcher, public thread::ThreadCore {
void RequestStop() override PW_LOCKS_EXCLUDED(lock_);
- // Returns the current time as viewed by the BasicDispatcher.
- chrono::SystemClock::time_point Now() override {
- return chrono::SystemClock::now();
- }
-
// Post caller owned |task|.
void PostTask(Task& task) override;
@@ -68,6 +63,13 @@ class BasicDispatcher final : public Dispatcher, public thread::ThreadCore {
void RunUntil(chrono::SystemClock::time_point end_time) override;
void RunFor(chrono::SystemClock::duration duration) override;
+ // VirtualSystemClock overrides:
+
+ // Returns the current time as viewed by the BasicDispatcher.
+ chrono::SystemClock::time_point now() override {
+ return chrono::SystemClock::now();
+ }
+
private:
// TestDispatcher uses BasicDispatcher methods operating on Task state.
friend class TestDispatcher;
diff --git a/pw_async/public_test/pw_async/test_dispatcher.h b/pw_async/public_test/pw_async/test_dispatcher.h
index 0c86026f1..2a396cb67 100644
--- a/pw_async/public_test/pw_async/test_dispatcher.h
+++ b/pw_async/public_test/pw_async/test_dispatcher.h
@@ -22,8 +22,6 @@ class TestDispatcher final : public Dispatcher {
explicit TestDispatcher() {}
~TestDispatcher() override { RequestStop(); }
- chrono::SystemClock::time_point Now() override { return now_; }
-
void RequestStop() override;
// Post caller owned |task|.
@@ -64,6 +62,10 @@ class TestDispatcher final : public Dispatcher {
// come due in that period.
void RunFor(chrono::SystemClock::duration duration) override;
+ // VirtualSystemClock overrides:
+
+ chrono::SystemClock::time_point now() override { return now_; }
+
private:
// Insert |task| into task_queue_ maintaining its min-heap property, keyed by
// |time_due|.
diff --git a/pw_async/test_dispatcher.cc b/pw_async/test_dispatcher.cc
index 66da26a69..64b484ab7 100644
--- a/pw_async/test_dispatcher.cc
+++ b/pw_async/test_dispatcher.cc
@@ -42,12 +42,12 @@ void TestDispatcher::RunUntil(chrono::SystemClock::time_point end_time) {
}
void TestDispatcher::RunFor(chrono::SystemClock::duration duration) {
- RunUntil(Now() + duration);
+ RunUntil(now() + duration);
}
void TestDispatcher::RunLoopOnce() {
while (!task_queue_.empty() &&
- BasicDispatcher::DueTime(task_queue_.front()) <= Now()) {
+ BasicDispatcher::DueTime(task_queue_.front()) <= now()) {
Task& task = task_queue_.front();
task_queue_.pop_front();
@@ -67,11 +67,11 @@ void TestDispatcher::RequestStop() {
task_queue_.clear();
}
-void TestDispatcher::PostTask(Task& task) { PostTaskForTime(task, Now()); }
+void TestDispatcher::PostTask(Task& task) { PostTaskForTime(task, now()); }
void TestDispatcher::PostDelayedTask(Task& task,
chrono::SystemClock::duration delay) {
- PostTaskForTime(task, Now() + delay);
+ PostTaskForTime(task, now() + delay);
}
void TestDispatcher::PostTaskForTime(Task& task,
@@ -82,7 +82,7 @@ void TestDispatcher::PostTaskForTime(Task& task,
void TestDispatcher::SchedulePeriodicTask(
Task& task, chrono::SystemClock::duration interval) {
- SchedulePeriodicTask(task, interval, Now());
+ SchedulePeriodicTask(task, interval, now());
}
void TestDispatcher::SchedulePeriodicTask(