1 // Copyright 2024 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 <tuple>
17
18 #include "pw_allocator/allocator.h"
19 #include "pw_channel/channel.h"
20 #include "pw_function/function.h"
21 #include "pw_rpc/server.h"
22
23 namespace pw {
24 namespace system {
25
26 class AsyncCore; // Forward declaration for function declaration.
27
28 } // namespace system
29
30 /// Returns a reference to the global pw_system instance. pw::System() provides
31 /// several features for applications: a memory allocator, an async dispatcher,
32 /// and a RPC server.
33 system::AsyncCore& System();
34
35 /// Starts running `pw_system:async` with the provided IO channel. This function
36 /// never returns.
37 [[noreturn]] void SystemStart(channel::ByteReaderWriter& io_channel);
38
39 namespace system {
40
41 /// The global `pw::System()` instance. This object is safe to access, whether
42 /// `pw::SystemStart` has been called or not.
43 class AsyncCore {
44 public:
45 /// Returns the system `pw::Allocator` instance.
46 Allocator& allocator();
47
48 /// Returns the system `pw::async2::Dispatcher` instance.
49 async2::Dispatcher& dispatcher();
50
51 /// Returns the system `pw::rpc::Server` instance.
rpc_server()52 rpc::Server& rpc_server() { return rpc_server_; }
53
54 /// Runs a function once on a separate thread. If the function blocks, it may
55 /// prevent other functions from running.
56 ///
57 /// @returns true if the function was enqueued to run, false if the function
58 /// queue is full
59 [[nodiscard]] bool RunOnce(Function<void()>&& function);
60
61 private:
62 friend AsyncCore& pw::System();
63 friend void pw::SystemStart(channel::ByteReaderWriter&);
64
AsyncCore()65 explicit _PW_RPC_CONSTEXPR AsyncCore()
66 : rpc_channels_{}, rpc_server_(rpc_channels_) {}
67
68 void Init(channel::ByteReaderWriter& io_channel);
69
70 static async2::Poll<> InitTask(async2::Context&);
71
72 rpc::Channel rpc_channels_[1];
73 rpc::Server rpc_server_;
74 };
75
76 } // namespace system
77
System()78 inline system::AsyncCore& System() {
79 _PW_RPC_CONSTINIT static system::AsyncCore system_core;
80 return system_core;
81 }
82
83 } // namespace pw
84