blob: 8d3275c2e56451c0bf5b4f1b0e0fdce5e7598ff0 [file] [log] [blame]
// Copyright 2022 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#pragma once
#include <bitset>
#include <optional>
#include "pw_span/span.h"
namespace pw::thread {
// The class ThreadInfo provides a summary of specific thread information and is
// used by thread iteration to dump thread info generically.
//
// Captures the following fields:
// stack_start_pointer
// stack_end_pointer
// stack_est_peak_pointer
// thread_name
class ThreadInfo {
public:
ThreadInfo() = default;
constexpr std::optional<uintptr_t> stack_low_addr() const {
return get_stack_info_ptr(kStackLowAddress);
}
void set_stack_low_addr(uintptr_t val) {
set_stack_info_ptr(kStackLowAddress, val);
}
void clear_stack_low_addr() { clear_stack_info_ptr(kStackLowAddress); }
constexpr std::optional<uintptr_t> stack_high_addr() const {
return get_stack_info_ptr(kStackHighAddress);
}
void set_stack_high_addr(uintptr_t val) {
set_stack_info_ptr(kStackHighAddress, val);
}
void clear_stack_high_addr() { clear_stack_info_ptr(kStackHighAddress); }
constexpr std::optional<uintptr_t> stack_peak_addr() const {
return get_stack_info_ptr(kStackPeakAddress);
}
void set_stack_peak_addr(uintptr_t val) {
set_stack_info_ptr(kStackPeakAddress, val);
}
void clear_stack_peak_addr() { clear_stack_info_ptr(kStackPeakAddress); }
constexpr std::optional<span<const std::byte>> thread_name() const {
return has_value_[kThreadName] ? std::make_optional(thread_name_)
: std::nullopt;
}
void set_thread_name(span<const std::byte> val) {
thread_name_ = val;
has_value_.set(kThreadName, true);
}
void clear_thread_name() { clear_stack_info_ptr(kThreadName); }
private:
enum ThreadInfoIndex {
kStackLowAddress,
kStackHighAddress,
kStackPeakAddress,
kThreadName,
kMaxNumMembersDoNotUse,
};
constexpr std::optional<uintptr_t> get_stack_info_ptr(
ThreadInfoIndex index) const {
return has_value_[index] ? std::make_optional(stack_info_ptrs_[index])
: std::nullopt;
}
void set_stack_info_ptr(ThreadInfoIndex index, uintptr_t val) {
stack_info_ptrs_[index] = val;
has_value_.set(index, true);
}
void clear_stack_info_ptr(ThreadInfoIndex index) {
has_value_.set(index, false);
}
std::bitset<ThreadInfoIndex::kMaxNumMembersDoNotUse> has_value_;
uintptr_t stack_info_ptrs_[ThreadInfoIndex::kMaxNumMembersDoNotUse];
span<const std::byte> thread_name_;
};
} // namespace pw::thread