#include "task_stats.h" #include #include #include namespace roro { std::vector taskRows(const std::vector& before, uint32_t totalBefore, const std::vector& now, uint32_t totalNow) { uint32_t elapsed = totalNow - totalBefore; // unsigned: right across one wrap std::vector rows; rows.reserve(now.size()); for (const TaskSample& t : now) { uint32_t ran = t.runtime; // a task that wasn't there before ran all of it since for (const TaskSample& b : before) if (b.id == t.id) { ran = t.runtime - b.runtime; break; } TaskRow r; r.name = t.name; r.core = t.core; r.state = t.state; r.priority = t.priority; r.stackFree = t.stackFree; r.permille = elapsed ? static_cast(std::min(1000, static_cast(ran) * 1000 / elapsed)) : 0; r.lowStack = t.stackFree < kLowStackBytes; r.idle = std::strncmp(t.name, "IDLE", 4) == 0; rows.push_back(r); } // The task that took the sample is running, and FreeRTOS counts a task's time when it's // switched out: with its core to itself it never was, and its counter hardly moved. Give it // what's left of its core once the idle task and the other tasks pinned there are counted. for (TaskRow& r : rows) { if (r.state != 0 || r.idle || r.core < 0) continue; // 0: eRunning int others = 0; bool idleSeen = false; for (const TaskRow& o : rows) { if (&o == &r || o.core != r.core) continue; others += o.permille; idleSeen |= o.idle; } if (idleSeen && elapsed && 1000 - others > r.permille) r.permille = static_cast(std::max(0, 1000 - others)); } return rows; } int coreLoad(const std::vector& rows, int core) { for (const TaskRow& r : rows) if (r.idle && r.core == core) return 100 - (r.permille + 5) / 10; return -1; } void sortTasks(std::vector& rows, TaskSort by) { auto lower = [](const std::string& s) { std::string l = s; for (char& c : l) c = static_cast(std::tolower(static_cast(c))); return l; }; std::stable_sort(rows.begin(), rows.end(), [&](const TaskRow& a, const TaskRow& b) { switch (by) { case TaskSort::Share: if (a.idle != b.idle) return !a.idle; // idle tasks last return a.permille > b.permille; case TaskSort::Stack: return a.stackFree < b.stackFree; default: return lower(a.name) < lower(b.name); } }); } } // namespace roro