Add a console command for task-level performance checks

custom
jacqueline 2 years ago
parent 40475b15e8
commit d71682d26e
  1. 96
      src/app_console/app_console.cpp

@ -7,11 +7,13 @@
#include "app_console.hpp" #include "app_console.hpp"
#include <dirent.h> #include <dirent.h>
#include <stdint.h>
#include <algorithm> #include <algorithm>
#include <cstdint> #include <cstdint>
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <iomanip>
#include <iostream> #include <iostream>
#include <ostream> #include <ostream>
#include <sstream> #include <sstream>
@ -25,6 +27,7 @@
#include "esp_log.h" #include "esp_log.h"
#include "event_queue.hpp" #include "event_queue.hpp"
#include "ff.h" #include "ff.h"
#include "freertos/projdefs.h"
#include "index.hpp" #include "index.hpp"
#include "track.hpp" #include "track.hpp"
@ -324,6 +327,98 @@ void RegisterDbDump() {
esp_console_cmd_register(&cmd); esp_console_cmd_register(&cmd);
} }
int CmdTaskStats(int argc, char** argv) {
static const std::string usage = "usage: task_stats";
if (argc != 1) {
std::cout << usage << std::endl;
return 1;
}
// Pad the number of tasks so that uxTaskGetSystemState still returns info if
// new tasks are started during measurement.
size_t num_tasks = uxTaskGetNumberOfTasks() + 4;
TaskStatus_t* start_status = new TaskStatus_t[num_tasks];
TaskStatus_t* end_status = new TaskStatus_t[num_tasks];
uint32_t start_elapsed_ticks = 0;
uint32_t end_elapsed_ticks = 0;
size_t start_num_tasks =
uxTaskGetSystemState(start_status, num_tasks, &start_elapsed_ticks);
vTaskDelay(pdMS_TO_TICKS(2500));
size_t end_num_tasks =
uxTaskGetSystemState(end_status, num_tasks, &end_elapsed_ticks);
std::vector<std::pair<uint32_t, std::string>> info_strings;
for (int i = 0; i < start_num_tasks; i++) {
int k = -1;
for (int j = 0; j < end_num_tasks; j++) {
if (start_status[i].xHandle == end_status[j].xHandle) {
k = j;
break;
}
}
if (k >= 0) {
uint32_t run_time =
end_status[k].ulRunTimeCounter - start_status[i].ulRunTimeCounter;
float time_percent =
static_cast<float>(run_time) /
static_cast<float>(end_elapsed_ticks - start_elapsed_ticks);
auto depth = uxTaskGetStackHighWaterMark2(start_status[i].xHandle);
float depth_kib = static_cast<float>(depth) / 1024.0f;
std::ostringstream str;
str << start_status[i].pcTaskName;
if (str.str().size() < 8) {
str << "\t\t";
} else {
str << "\t";
}
str << std::fixed << std::setprecision(1) << depth_kib;
str << " KiB";
if (depth_kib >= 10) {
str << "\t";
} else {
str << "\t\t";
}
str << std::fixed << std::setprecision(1) << time_percent * 100;
str << "%";
info_strings.push_back({run_time, str.str()});
}
}
std::sort(info_strings.begin(), info_strings.end(),
[](const auto& first, const auto& second) {
return first.first >= second.first;
});
std::cout << "name\t\tfree stack\trun time" << std::endl;
for (const auto& i : info_strings) {
std::cout << i.second << std::endl;
}
delete[] start_status;
delete[] end_status;
return 0;
}
void RegisterTaskStates() {
esp_console_cmd_t cmd{.command = "task_stats",
.help = "prints performance info for all tasks",
.hint = NULL,
.func = &CmdTaskStats,
.argtable = NULL};
esp_console_cmd_register(&cmd);
}
auto AppConsole::RegisterExtraComponents() -> void { auto AppConsole::RegisterExtraComponents() -> void {
RegisterListDir(); RegisterListDir();
RegisterPlayFile(); RegisterPlayFile();
@ -336,6 +431,7 @@ auto AppConsole::RegisterExtraComponents() -> void {
RegisterDbTracks(); RegisterDbTracks();
RegisterDbIndex(); RegisterDbIndex();
RegisterDbDump(); RegisterDbDump();
RegisterTaskStates();
} }
} // namespace console } // namespace console

Loading…
Cancel
Save