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/internal/types.h" 17 #include "pw_chrono/system_clock.h" 18 #include "pw_containers/intrusive_list.h" 19 20 namespace pw::async { 21 class BasicDispatcher; 22 namespace test::backend { 23 class NativeFakeDispatcher; 24 } 25 } // namespace pw::async 26 27 namespace pw::async::backend { 28 29 // Task backend for BasicDispatcher. 30 class NativeTask final : public IntrusiveList<NativeTask>::Item { 31 private: 32 friend class ::pw::async::Task; 33 friend class ::pw::async::BasicDispatcher; 34 friend class ::pw::async::test::backend::NativeFakeDispatcher; 35 NativeTask(::pw::async::Task & task)36 NativeTask(::pw::async::Task& task) : task_(task) {} NativeTask(::pw::async::Task & task,TaskFunction && f)37 explicit NativeTask(::pw::async::Task& task, TaskFunction&& f) 38 : func_(std::move(f)), task_(task) {} operator()39 void operator()(Context& ctx, Status status) { func_(ctx, status); } set_function(TaskFunction && f)40 void set_function(TaskFunction&& f) { func_ = std::move(f); } 41 due_time()42 pw::chrono::SystemClock::time_point due_time() const { return due_time_; } set_due_time(chrono::SystemClock::time_point due_time)43 void set_due_time(chrono::SystemClock::time_point due_time) { 44 due_time_ = due_time; 45 } interval()46 std::optional<chrono::SystemClock::duration> interval() const { 47 if (interval_ == chrono::SystemClock::duration::zero()) { 48 return std::nullopt; 49 } 50 return interval_; 51 } set_interval(std::optional<chrono::SystemClock::duration> interval)52 void set_interval(std::optional<chrono::SystemClock::duration> interval) { 53 if (!interval.has_value()) { 54 interval_ = chrono::SystemClock::duration::zero(); 55 return; 56 } 57 interval_ = *interval; 58 } 59 60 TaskFunction func_ = nullptr; 61 // task_ is placed after func_ to take advantage of the padding that would 62 // otherwise be added here. On 32-bit systems, func_ and due_time_ have an 63 // alignment of 8, but func_ has a size of 12 by default. Thus, 4 bytes of 64 // padding would be added here, which is just enough for a pointer. 65 Task& task_; 66 pw::chrono::SystemClock::time_point due_time_; 67 // A duration of 0 indicates that the task is not periodic. 68 chrono::SystemClock::duration interval_ = 69 chrono::SystemClock::duration::zero(); 70 }; 71 72 using NativeTaskHandle = NativeTask&; 73 74 } // namespace pw::async::backend 75