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