xref: /aosp_15_r20/external/pigweed/pw_thread/public/pw_thread/thread_snapshot_service.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2022 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_rpc/raw/server_reader_writer.h"
17 #include "pw_span/span.h"
18 #include "pw_status/status.h"
19 #include "pw_thread/config.h"
20 #include "pw_thread/thread_info.h"
21 #include "pw_thread_protos/thread.pwpb.h"
22 #include "pw_thread_protos/thread_snapshot_service.pwpb.h"
23 #include "pw_thread_protos/thread_snapshot_service.raw_rpc.pb.h"
24 
25 namespace pw::thread::proto {
26 
27 Status ProtoEncodeThreadInfo(pwpb::SnapshotThreadInfo::StreamEncoder& encoder,
28                              const ThreadInfo& thread_info);
29 
30 // Calculates encoded buffer size based on code gen constants.
31 constexpr size_t RequiredServiceBufferSize(
32     size_t num_threads = PW_THREAD_MAXIMUM_THREADS) {
33   constexpr size_t kSizeOfResponse =
34       pwpb::SnapshotThreadInfo::kMaxEncodedSizeBytes +
35       pwpb::Thread::kMaxEncodedSizeBytes;
36   return kSizeOfResponse * num_threads;
37 }
38 
39 // The ThreadSnapshotService will return peak stack usage across running
40 // threads when requested by GetPeak().
41 //
42 // Parameter encode_buffer: buffer where thread information is encoded. Size
43 // depends on RequiredBufferSize().
44 //
45 // Parameter thread_proto_indices: array keeping track of thread boundaries in
46 // the encode buffer. The service uses these indices to send response data out
47 // in bundles.
48 //
49 // Parameter num_bundled_threads: constant describing number of threads per
50 // bundle in response.
51 class ThreadSnapshotService
52     : public pw_rpc::raw::ThreadSnapshotService::Service<
53           ThreadSnapshotService> {
54  public:
55   constexpr ThreadSnapshotService(
56       span<std::byte> encode_buffer,
57       Vector<size_t>& thread_proto_indices,
58       size_t num_bundled_threads = PW_THREAD_NUM_BUNDLED_THREADS)
encode_buffer_(encode_buffer)59       : encode_buffer_(encode_buffer),
60         thread_proto_indices_(thread_proto_indices),
61         num_bundled_threads_(num_bundled_threads) {}
62   void GetPeakStackUsage(ConstByteSpan request, rpc::RawServerWriter& response);
63 
64  private:
65   span<std::byte> encode_buffer_;
66   Vector<size_t>& thread_proto_indices_;
67   size_t num_bundled_threads_;
68 };
69 
70 // A ThreadSnapshotService that allocates required buffers based on the
71 // number of running threads on a device.
72 template <size_t kNumThreads = PW_THREAD_MAXIMUM_THREADS>
73 class ThreadSnapshotServiceBuffer : public ThreadSnapshotService {
74  public:
ThreadSnapshotServiceBuffer()75   ThreadSnapshotServiceBuffer()
76       : ThreadSnapshotService(encode_buffer_, thread_proto_indices_) {}
77 
78  private:
79   std::array<std::byte, RequiredServiceBufferSize(kNumThreads)> encode_buffer_;
80   // + 1 is needed to account for extra index that comes with the first
81   // submessage start or the last submessage end.
82   Vector<size_t, kNumThreads + 1> thread_proto_indices_;
83 };
84 
85 }  // namespace pw::thread::proto
86