Pigweed
 
Loading...
Searching...
No Matches
dispatcher.h
1// Copyright 2023 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 "pw_async/dispatcher.h"
17#include "pw_async/task.h"
18#include "pw_sync/interrupt_spin_lock.h"
19#include "pw_sync/lock_annotations.h"
20#include "pw_sync/timed_thread_notification.h"
21#include "pw_thread/thread_core.h"
22
23namespace pw::async {
24
26class BasicDispatcher : public Dispatcher, public thread::ThreadCore {
27 public:
28 explicit BasicDispatcher() = default;
29 ~BasicDispatcher() override;
30
33
36 void RunUntil(chrono::SystemClock::time_point end_time);
37
41
46 void RequestStop() PW_LOCKS_EXCLUDED(lock_);
47
48 // ThreadCore overrides:
49
53 void Run() override PW_LOCKS_EXCLUDED(lock_);
54
55 // Dispatcher overrides:
56 void PostAt(Task& task, chrono::SystemClock::time_point time) override;
57 bool Cancel(Task& task) override PW_LOCKS_EXCLUDED(lock_);
58
59 // VirtualSystemClock overrides:
60 chrono::SystemClock::time_point now() override {
62 }
63
64 protected:
69 virtual void ExecuteTask(backend::NativeTask& task, Status status)
70 PW_LOCKS_EXCLUDED(lock_);
71
72 private:
73 // Insert |task| into task_queue_ maintaining its min-heap property, keyed by
74 // |time_due|.
75 void PostTaskInternal(backend::NativeTask& task,
76 chrono::SystemClock::time_point time_due)
77 PW_LOCKS_EXCLUDED(lock_);
78
79 // If no tasks are due, sleep until a notification is received or the next
80 // task comes due; whichever occurs first.
81 void MaybeSleep() PW_EXCLUSIVE_LOCKS_REQUIRED(lock_);
82
83 // If no tasks are due, sleep until a notification is received, the next task
84 // comes due, or a timeout elapses; whichever occurs first.
85 void MaybeSleepUntil(std::optional<chrono::SystemClock::time_point> wake_time)
86 PW_EXCLUSIVE_LOCKS_REQUIRED(lock_);
87
88 // Dequeue and run each task that is due.
89 void ExecuteDueTasks() PW_EXCLUSIVE_LOCKS_REQUIRED(lock_);
90
91 // Dequeue each task and call each TaskFunction with a PW_STATUS_CANCELLED
92 // status.
93 void DrainTaskQueue() PW_EXCLUSIVE_LOCKS_REQUIRED(lock_);
94
95 sync::InterruptSpinLock lock_;
96 sync::TimedThreadNotification timed_notification_;
97 bool stop_requested_ PW_GUARDED_BY(lock_) = false;
98 // A priority queue of scheduled Tasks sorted by earliest due times first.
99 IntrusiveList<backend::NativeTask> task_queue_ PW_GUARDED_BY(lock_);
100};
101
102} // namespace pw::async
Definition: status.h:85
BasicDispatcher is a generic implementation of Dispatcher.
Definition: dispatcher.h:26
void RunUntilIdle()
Execute all runnable tasks and return without waiting.
void RunUntil(chrono::SystemClock::time_point end_time)
virtual void ExecuteTask(backend::NativeTask &task, Status status)
chrono::SystemClock::time_point now() override
Returns the current time.
Definition: dispatcher.h:60
void PostAt(Task &task, chrono::SystemClock::time_point time) override
void RunFor(chrono::SystemClock::duration duration)
bool Cancel(Task &task) override
Definition: dispatcher.h:45
Definition: task.h:31
Definition: intrusive_list.h:82
static time_point now() noexcept
This is thread and IRQ safe. This must be provided by the backend.
Definition: system_clock.h:113
std::chrono::duration< rep, period > duration
Alias for durations representable with this clock.
Definition: system_clock.h:86