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 final : 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 private:
65 // Insert |task| into task_queue_ maintaining its min-heap property, keyed by
66 // |time_due|.
67 void PostTaskInternal(backend::NativeTask& task,
68 chrono::SystemClock::time_point time_due)
69 PW_LOCKS_EXCLUDED(lock_);
70
71 // If no tasks are due, sleep until a notification is received, the next task
72 // comes due, or a timeout elapses; whichever occurs first.
73 void MaybeSleep() PW_EXCLUSIVE_LOCKS_REQUIRED(lock_);
74
75 // Dequeue and run each task that is due.
76 void ExecuteDueTasks() PW_EXCLUSIVE_LOCKS_REQUIRED(lock_);
77
78 // Dequeue each task and call each TaskFunction with a PW_STATUS_CANCELLED
79 // status.
80 void DrainTaskQueue() PW_EXCLUSIVE_LOCKS_REQUIRED(lock_);
81
82 sync::InterruptSpinLock lock_;
83 sync::TimedThreadNotification timed_notification_;
84 bool stop_requested_ PW_GUARDED_BY(lock_) = false;
85 // A priority queue of scheduled Tasks sorted by earliest due times first.
86 IntrusiveList<backend::NativeTask> task_queue_ PW_GUARDED_BY(lock_);
87};
88
89} // namespace pw::async
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)
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
static time_point now() noexcept
This is thread and IRQ safe. This must be provided by the backend.
Definition: system_clock.h:111
std::chrono::duration< rep, period > duration
Alias for durations representable with this clock.
Definition: system_clock.h:84