Thread Profiler

[中文]

Public header: #include "brookesia/lib_utils/thread_profiler.hpp"

Overview

thread_profiler samples task and thread state and CPU usage, helping analyze system load and hot tasks.

Features

  • Task status, CPU usage, stack info

  • Periodic profiling and manual snapshots

  • Sorting, filtering, and thresholds

  • Optional TaskScheduler integration

API Reference

Header File

Classes

class ThreadProfiler

FreeRTOS task profiler for CPU and stack usage monitoring.

This class provides a C++ interface to monitor FreeRTOS task CPU usage, stack usage, and other runtime statistics. It integrates naturally with TaskScheduler for periodic profiling.

Public Types

enum class TaskState

Task state mirrored from FreeRTOS eTaskState.

Values:

enumerator Running

eRunning.

enumerator Ready

eReady.

enumerator Blocked

eBlocked.

enumerator Suspended

eSuspended.

enumerator Deleted

eDeleted.

enumerator Invalid

eInvalid.

enum class TaskStatus

Presence status of a task across two samples.

Values:

enumerator Normal

Task exists in both samples.

enumerator Created

Task appeared during the measurement window.

enumerator Deleted

Task disappeared during the measurement window.

enum class PrimarySortBy

Optional primary sort criterion.

Values:

enumerator None

Disable primary sorting.

enumerator CoreId

Sort by CPU core ID first.

enum class SecondarySortBy

Secondary sort criterion applied within the primary ordering.

Values:

enumerator CpuPercent

Sort by CPU usage percentage in descending order.

enumerator Priority

Sort by task priority in descending order.

enumerator StackUsage

Sort by stack high-water mark in ascending order.

enumerator Name

Sort by task name alphabetically.

enum class ThresholdType

Metric used for threshold filtering and callbacks.

Values:

enumerator CpuPercent

Filter by CPU usage percentage.

enumerator Priority

Filter by task priority.

enumerator StackUsage

Filter by stack high-water mark.

using ProfilingSignalSlot = std::function<void(const ProfileSnapshot&)>

Callback type accepted by connect_profiling_signal().

using ThresholdSignalSlot = std::function<void(const std::vector<TaskInfo>&)>

Callback type accepted by connect_threshold_signal().

using ProfilingSignal = boost::signals2::signal<void(const ProfileSnapshot&)>

Signal type emitted for each profiling snapshot.

using ThresholdSignal = boost::signals2::signal<void(const std::vector<TaskInfo>&)>

Signal type emitted when threshold matches are found.

using SignalConnection = boost::signals2::scoped_connection

Signal connection type.

Note

This is an RAII smart handle for managing the lifetime of callbacks. When this object is destroyed, the corresponding callback is automatically disconnected. It is recommended to use std::move() to transfer ownership for manual management of the connection lifetime.

Public Functions

ThreadProfiler(const ThreadProfiler&) = delete

Copy construction is not supported.

ThreadProfiler &operator=(const ThreadProfiler&) = delete

Copy assignment is not supported.

ThreadProfiler(ThreadProfiler&&) = delete

Move construction is not supported.

ThreadProfiler &operator=(ThreadProfiler&&) = delete

Move assignment is not supported.

bool configure_profiling(const ProfilingConfig &config)

Update the profiling configuration.

Parameters

config – New profiler configuration.

Returns

true after the configuration is stored.

ProfilingConfig get_profiling_config() const

Get the current profiling configuration.

Returns

Active ProfilingConfig.

bool start_profiling(std::shared_ptr<TaskScheduler> scheduler, uint32_t sampling_duration_ms = 0, uint32_t profiling_interval_ms = 0)

Start periodic thread profiling using a task scheduler.

Parameters
  • scheduler – Scheduler used to run the two-stage sampling jobs. The caller must keep it alive until stop_profiling() returns.

  • sampling_duration_ms – Time between the first and second sample in milliseconds. Pass 0 to use config.sampling_duration_ms.

  • profiling_interval_ms – Period between profiling rounds in milliseconds. Pass 0 to use config.profiling_interval_ms.

Returns

true on success, or false if profiling cannot be started.

void stop_profiling()

Stop periodic profiling.

void reset_profiling()

Reset captured data and registered callbacks without changing configuration.

inline bool is_profiling() const

Check whether periodic profiling is active.

Returns

true when profiling tasks are active, or false otherwise.

inline std::shared_ptr<ProfileSnapshot> get_profiling_latest_snapshot()

Get the latest captured profiling snapshot.

Returns

Shared pointer to the latest snapshot, or nullptr if none is available.

SignalConnection connect_profiling_signal(ProfilingSignalSlot slot)

Subscribe to every generated profiling snapshot.

Parameters

slot – Callback invoked whenever a new snapshot is produced.

Returns

RAII connection handle for the registered callback.

SignalConnection connect_threshold_signal(ThresholdType type, uint32_t threshold_value, ThresholdSignalSlot slot)

Subscribe to threshold matches for a specific metric.

Parameters
  • type – Metric to monitor.

  • threshold_value – Threshold value interpreted according to type.

  • slot – Callback invoked with the tasks that matched the threshold.

Returns

RAII connection handle for the registered callback.

Public Static Functions

static inline ThreadProfiler &get_instance()

Get the process-wide singleton instance.

Returns

Reference to the singleton profiler.

static std::shared_ptr<SampleResult> sample_tasks()

Capture a single raw scheduler sample.

Returns

Shared pointer to the captured sample, or nullptr on failure.

static std::shared_ptr<ProfileSnapshot> take_snapshot(const SampleResult &start_result, const SampleResult &end_result)

Build a profiling snapshot from two raw samples.

Parameters
  • start_result – Sample taken at the beginning of the measurement window.

  • end_result – Sample taken at the end of the measurement window.

Returns

Shared pointer to the computed snapshot, or nullptr on failure.

static void sort_tasks(std::vector<TaskInfo> &tasks, PrimarySortBy primary_sort = PrimarySortBy::CoreId, SecondarySortBy secondary_sort = SecondarySortBy::CpuPercent)

Sort task entries in place.

Note

The tasks will be sorted by the primary sort criteria first, then by the secondary sort criteria.

Parameters
  • tasks – Task vector to sort in place.

  • primary_sort – Optional primary sort criterion.

  • secondary_sort – Secondary sort criterion.

static void print_snapshot(const ProfileSnapshot &snapshot, PrimarySortBy primary_sort = PrimarySortBy::CoreId, SecondarySortBy secondary_sort = SecondarySortBy::CpuPercent)

Print a formatted snapshot table to the log.

Parameters
  • snapshot – Snapshot to print.

  • primary_sort – Primary sort criterion shown in the first sort column.

  • secondary_sort – Secondary sort criterion shown in the second sort column.

static bool get_task_by_name(const ProfileSnapshot &snapshot, const std::string &name, TaskInfo &task)

Find a task by name inside a snapshot.

Parameters
  • snapshot – Snapshot to search.

  • name – Task name to search for.

  • task – Output object that receives the matching task info.

Returns

true if a matching task is found, or false otherwise.

static std::vector<TaskInfo> get_tasks_above_threshold(const ProfileSnapshot &snapshot, ThresholdType type, uint32_t threshold_value)

Collect tasks whose metric meets a threshold.

Note

For CpuPercent: returns tasks with CPU >= threshold_value For Priority: returns tasks with priority >= threshold_value For StackUsage: returns tasks with stack HWM <= threshold_value (lower = more used)

Parameters
  • snapshot – Snapshot to inspect.

  • type – Threshold metric to apply.

  • threshold_value – Threshold value interpreted according to type.

Returns

Vector containing every task that satisfies the threshold.

struct ProfileSnapshot

Snapshot of all sampled task information.

Public Members

std::chrono::system_clock::time_point timestamp = {}

Snapshot capture time.

std::vector<TaskInfo> tasks

Task data for every sampled task.

Statistics stats = {}

Aggregate snapshot statistics.

uint32_t total_runtime = 0

Total runtime counter captured in the ending sample.

struct ProfilingConfig

Configuration for periodic thread profiling.

Public Members

uint32_t sampling_duration_ms = 1000

Delay between the start and end sample, in milliseconds.

uint32_t profiling_interval_ms = 5000

Interval between profiling rounds, in milliseconds.

PrimarySortBy primary_sort = PrimarySortBy::CoreId

Primary sort criterion.

SecondarySortBy secondary_sort = SecondarySortBy::CpuPercent

Secondary sort criterion.

bool enable_auto_logging = true

Whether to log each generated snapshot automatically.

struct SampleResult

Raw sample captured at a single instant.

Public Members

std::chrono::system_clock::time_point timestamp

Sample capture time.

std::vector<TaskStatus_t> task_status

Raw FreeRTOS task status array.

uint32_t runtime

Raw total runtime counter.

struct Statistics

Aggregate statistics for a profiling snapshot.

Public Members

size_t total_tasks = 0

Total number of tasks in the snapshot.

size_t running_tasks = 0

Number of running tasks.

size_t blocked_tasks = 0

Number of blocked tasks.

size_t suspended_tasks = 0

Number of suspended tasks.

uint32_t total_cpu_percent = 0

Aggregate CPU usage percentage.

uint32_t sample_duration_ms = 0

Measurement window duration in milliseconds.

struct TaskInfo

Profile data for a single FreeRTOS task.

Public Members

std::string name

Task name.

TaskHandle_t handle = nullptr

FreeRTOS task handle.

TaskState state = TaskState::Invalid

Current task state.

uint32_t priority = 0

Current task priority.

BaseType_t core_id = -1

Bound CPU core ID, or -1 if unbound.

uint32_t stack_high_water_mark = 0

Stack high-water mark in bytes.

bool is_stack_external = false

Whether the stack is allocated in external RAM.

uint32_t runtime_counter = 0

Raw runtime counter captured in the ending sample.

uint32_t elapsed_time = 0

Runtime counter delta during the measurement window.

uint32_t cpu_percent = 0

CPU usage percentage over the measurement window.

TaskStatus status = TaskStatus::Normal

Presence status relative to the two samples.