xref: /aosp_15_r20/external/pigweed/pw_thread/public/pw_thread/thread_info.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 <bitset>
17 #include <cstdint>
18 #include <optional>
19 
20 #include "pw_span/span.h"
21 
22 namespace pw::thread {
23 
24 // The class ThreadInfo provides a summary of specific thread information and is
25 // used by thread iteration to dump thread info generically.
26 //
27 // Captures the following fields:
28 //     stack_start_pointer
29 //     stack_end_pointer
30 //     stack_est_peak_pointer
31 //     thread_name
32 class ThreadInfo {
33  public:
34   ThreadInfo() = default;
35 
stack_low_addr()36   constexpr std::optional<uintptr_t> stack_low_addr() const {
37     return get_stack_info_ptr(kStackLowAddress);
38   }
39 
set_stack_low_addr(uintptr_t val)40   void set_stack_low_addr(uintptr_t val) {
41     set_stack_info_ptr(kStackLowAddress, val);
42   }
43 
clear_stack_low_addr()44   void clear_stack_low_addr() { clear_stack_info_ptr(kStackLowAddress); }
45 
stack_high_addr()46   constexpr std::optional<uintptr_t> stack_high_addr() const {
47     return get_stack_info_ptr(kStackHighAddress);
48   }
49 
set_stack_high_addr(uintptr_t val)50   void set_stack_high_addr(uintptr_t val) {
51     set_stack_info_ptr(kStackHighAddress, val);
52   }
53 
clear_stack_high_addr()54   void clear_stack_high_addr() { clear_stack_info_ptr(kStackHighAddress); }
55 
stack_pointer()56   constexpr std::optional<uintptr_t> stack_pointer() const {
57     return get_stack_info_ptr(kStackPointer);
58   }
59 
set_stack_pointer(uintptr_t val)60   void set_stack_pointer(uintptr_t val) {
61     set_stack_info_ptr(kStackPointer, val);
62   }
63 
clear_stack_pointer()64   void clear_stack_pointer() { clear_stack_info_ptr(kStackPointer); }
65 
stack_peak_addr()66   constexpr std::optional<uintptr_t> stack_peak_addr() const {
67     return get_stack_info_ptr(kStackPeakAddress);
68   }
69 
set_stack_peak_addr(uintptr_t val)70   void set_stack_peak_addr(uintptr_t val) {
71     set_stack_info_ptr(kStackPeakAddress, val);
72   }
73 
clear_stack_peak_addr()74   void clear_stack_peak_addr() { clear_stack_info_ptr(kStackPeakAddress); }
75 
thread_name()76   constexpr std::optional<span<const std::byte>> thread_name() const {
77     return has_value_[kThreadName] ? std::make_optional(thread_name_)
78                                    : std::nullopt;
79   }
80 
set_thread_name(span<const std::byte> val)81   void set_thread_name(span<const std::byte> val) {
82     thread_name_ = val;
83     has_value_.set(kThreadName, true);
84   }
85 
clear_thread_name()86   void clear_thread_name() { clear_stack_info_ptr(kThreadName); }
87 
88  private:
89   enum ThreadInfoIndex {
90     kStackLowAddress,
91     kStackHighAddress,
92     kStackPointer,
93     kStackPeakAddress,
94     kThreadName,
95     kMaxNumMembersDoNotUse,
96   };
97 
get_stack_info_ptr(ThreadInfoIndex index)98   constexpr std::optional<uintptr_t> get_stack_info_ptr(
99       ThreadInfoIndex index) const {
100     return has_value_[index] ? std::make_optional(stack_info_ptrs_[index])
101                              : std::nullopt;
102   }
103 
set_stack_info_ptr(ThreadInfoIndex index,uintptr_t val)104   void set_stack_info_ptr(ThreadInfoIndex index, uintptr_t val) {
105     stack_info_ptrs_[index] = val;
106     has_value_.set(index, true);
107   }
108 
clear_stack_info_ptr(ThreadInfoIndex index)109   void clear_stack_info_ptr(ThreadInfoIndex index) {
110     has_value_.set(index, false);
111   }
112 
113   std::bitset<ThreadInfoIndex::kMaxNumMembersDoNotUse> has_value_;
114   uintptr_t stack_info_ptrs_[ThreadInfoIndex::kMaxNumMembersDoNotUse];
115   span<const std::byte> thread_name_;
116 };
117 
118 }  // namespace pw::thread
119