diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ebc7991 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +gtop \ No newline at end of file diff --git a/Makefile b/Makefile index 861608c..6771b75 100644 --- a/Makefile +++ b/Makefile @@ -6,3 +6,9 @@ fake: travis: $(CXX) -std=c++14 gtop.cc utils.cc display.cc -o gtop -pedantic -Wall -Wextra -lncurses -lpthread + +install: all + cp gtop /usr/local/bin + +unistall: + rm -f /usr/local/bin/gtop \ No newline at end of file diff --git a/display.cc b/display.cc index a3da1fe..46331b9 100644 --- a/display.cc +++ b/display.cc @@ -25,11 +25,26 @@ void display_bars(const int & row, const int & col, const int & val, const int & mvprintw(row, col+b.max_bar+1, "%3d%%", val); display_right_bracket(); - printw(" %d", freq); + printw(" %dHz", freq); refresh(); } +void display_power_bars(const int & row, const int & col, const int & current, const int & maximum) { + int val = 100 * (static_cast(current) / static_cast(maximum)); + auto b = update_bar_dims(val); + clear_row(row, col); + + display_left_bracket(row, col); + display_bars(b.val_bar); + + mvprintw(row, col+b.max_bar+1, "%3d%%", val); + display_right_bracket(); + printw(" %d/%dmW", current, maximum); + + refresh(); +} + void display_mem_bars(const int & row, const int & col, const int & val, const int & max_val) { auto val_norm = int((float(val) / max_val) * 100); auto b = update_bar_dims(val_norm); @@ -41,7 +56,7 @@ void display_mem_bars(const int & row, const int & col, const int & val, const i char buffer[MEM_BUFFER_SIZE]; sprintf(buffer, "%2.2fG/%2.2fG", mega2giga(val), mega2giga(max_val)); - mvprintw(row, col+b.max_bar-6, buffer); + mvprintw(row, col+b.max_bar-7, buffer); display_right_bracket(); refresh(); } @@ -108,14 +123,16 @@ void display_cpu_stats(const int & row, const tegrastats & ts) { int idx = 0; for (const auto & u : ts.cpu_usage) { const auto cpu_label = std::string("CPU ") + std::to_string(idx); - attron(COLOR_PAIR(idx+1)); + attron(COLOR_PAIR((idx+1) % COLOR_COUNT)); mvprintw(row+idx, 0, cpu_label.c_str()); - attroff(COLOR_PAIR(idx+1)); + attroff(COLOR_PAIR((idx+1) % COLOR_COUNT)); if (ts.version == TX1) display_bars(row+idx, BAR_OFFSET, u, ts.cpu_freq.at(0)); else if (ts.version == TX2) display_bars(row+idx, BAR_OFFSET, u, ts.cpu_freq.at(idx)); + else if (ts.version == AGX) + display_bars(row+idx, BAR_OFFSET, u, ts.cpu_freq.at(idx)); idx++; } @@ -126,6 +143,11 @@ void display_gpu_stats(const int & row, const tegrastats & ts) { display_bars(row, BAR_OFFSET, ts.gpu_usage, ts.gpu_freq); } +void display_dla_power_stats(const int & row, const tegrastats & ts) { + mvprintw(row, 0, "CV Pow"); + display_power_bars(row, BAR_OFFSET, ts.dla_power, ts.dla_power_max); +} + void display_mem_stats(const int & row, const tegrastats & ts) { mvprintw(row, 0, "Mem"); display_mem_bars(row, BAR_OFFSET, ts.mem_usage, ts.mem_max); @@ -149,9 +171,9 @@ void display_usage_chart(const int & row, const std::vector> cp } int tmp_cpu_usage = int((max_height/100.0)*cpu_usage); - attron(COLOR_PAIR(idx)); + attron(COLOR_PAIR(idx % COLOR_COUNT)); mvprintw(max_height-tmp_cpu_usage+row, col+3, "*"); - attroff(COLOR_PAIR(idx)); + attroff(COLOR_PAIR(idx % COLOR_COUNT)); idx++; } diff --git a/display.hh b/display.hh index 9c68a8d..9aadc41 100644 --- a/display.hh +++ b/display.hh @@ -14,6 +14,7 @@ const int BAR_OFFSET = 6; const int MIN_HEIGHT_USAGE_CHART = 30; +const int COLOR_COUNT = 7; enum colors {RED_BLACK=1, GREEN_BLACK, YELLOW_BLACK, @@ -58,6 +59,8 @@ struct dimensions { void display_bars(const int &, const int &, const int &); void display_bars(const int &, const int &, const int &, const int &); void display_bars(const int &); +void display_power_bars(const int &, const int &, const int &, const int &); + void display_mem_bars(const int &, const int &, const int &, const int &); float mega2giga(const int &); bar update_bar_dims(const int &); @@ -68,7 +71,9 @@ void clear_row(const int &, const int &); void display_cpu_stats(const int &, const tegrastats &); void display_gpu_stats(const int &, const tegrastats &); +void display_dla_power_stats(const int &, const tegrastats &); void display_mem_stats(const int &, const tegrastats &); + void display_usage_chart(const int &, const std::vector>); #endif // DISPLAY_HH_ diff --git a/gtop.cc b/gtop.cc index d511ebc..746d1cb 100644 --- a/gtop.cc +++ b/gtop.cc @@ -11,13 +11,13 @@ bool processed = false; bool ready = false; bool finished = false; -int main() { +int main() { if (getuid()) { std::cout << "gtop requires root privileges!" << std::endl; exit(1); } - std::thread t(read_tegrastats); + std::thread t(read_tegrastats); initscr(); noecho(); @@ -51,7 +51,7 @@ int main() { // CPU USAGE CHART update_usage_chart(cpu_usage_buffer, t_stats.cpu_usage); - display_usage_chart(10, cpu_usage_buffer); + display_usage_chart(11, cpu_usage_buffer); lk.unlock(); @@ -62,7 +62,7 @@ int main() { break; } - { + { std::lock_guard lk(m); finished = true; } @@ -104,7 +104,7 @@ void read_tegrastats() { cv.wait(lk, []{ return ready; }); ready = false; - t_stats = parse_tegrastats(buffer.data()); + parse_tegrastats(buffer.data(), t_stats); processed = true; lk.unlock(); cv.notify_one(); @@ -112,14 +112,19 @@ void read_tegrastats() { } } -tegrastats parse_tegrastats(const char * buffer) { - tegrastats ts; +void parse_tegrastats(const char * buffer, tegrastats &ts) { + + ts.cpu_freq.clear(); + ts.cpu_usage.clear(); auto stats = tokenize(buffer, ' '); - if (stats.size() >= 15) + if (stats.size() >= 30) { + ts.version = AGX; + } else if (stats.size() >= 15) { ts.version = TX1; - else + } else { ts.version = TX2; + } get_mem_stats(ts, stats.at(1)); @@ -132,11 +137,14 @@ tegrastats parse_tegrastats(const char * buffer) { get_cpu_stats_tx2(ts, stats.at(5)); get_gpu_stats(ts, stats.at(13)); break; + case AGX: + get_cpu_stats_tx2(ts, stats.at(9)); + get_gpu_stats(ts, stats.at(13)); + get_dla_power_stats(ts, stats.at(36)); + break; case TK1: // TODO break; } - - return ts; } void get_cpu_stats_tx1(tegrastats & ts, const std::string & str) { @@ -158,7 +166,7 @@ void get_cpu_stats_tx2(tegrastats & ts, const std::string & str) { const auto at = std::string("@"); for (const auto & u: cpu_stats) { - if (u != "off") { + if (u != "off" && u != "off]" && u != "[off") { std::size_t found = at.find(u); if (found == std::string::npos) { auto cpu_info = tokenize(u, at.c_str()[0]); @@ -189,15 +197,30 @@ void get_mem_stats(tegrastats & ts, const std::string & str) { ts.mem_max = std::stoi(mem_max.substr(0, mem_max.size()-2)); } +void get_dla_power_stats(tegrastats & ts, const std::string & str) { + const auto mem_stats = tokenize(str, '/'); + + ts.dla_power = std::stoi(mem_stats.at(0)); + ts.dla_power_avg = std::stoi(mem_stats.at(1)); + ts.dla_power_max = std::max(ts.dla_power_max, ts.dla_power); +} + void display_stats(const dimensions & d, const tegrastats & ts) { // CPU display_cpu_stats(0, ts); // GPU - display_gpu_stats(ts.cpu_usage.size(), ts); + int pos = ts.cpu_usage.size(); + display_gpu_stats(pos, ts); + + if(ts.version == AGX) { + pos++; + display_dla_power_stats(pos, ts); + } + pos++; // Memory - display_mem_stats(ts.cpu_usage.size()+1, ts); + display_mem_stats(pos, ts); } void update_usage_chart(std::vector> & usage_buffer, diff --git a/gtop.hh b/gtop.hh index f601067..f075db8 100644 --- a/gtop.hh +++ b/gtop.hh @@ -21,18 +21,19 @@ #include "display.hh" #include "utils.hh" -const int STATS_BUFFER_SIZE = 256; +const int STATS_BUFFER_SIZE = 512; -const std::string TEGRASTATS_PATH = "~/tegrastats"; +const std::string TEGRASTATS_PATH = "/usr/bin/tegrastats"; const std::string TEGRASTATSFAKE_PATH = "./tegrastats_fake"; void read_tegrastats(); -tegrastats parse_tegrastats(const char *); +void parse_tegrastats(const char * buffer, tegrastats &ts); void get_cpu_stats_tx1(tegrastats &, const std::string &); void get_cpu_stats_tx2(tegrastats &, const std::string &); void get_gpu_stats(tegrastats &, const std::string &); void get_mem_stats(tegrastats &, const std::string &); +void get_dla_power_stats(tegrastats &, const std::string &); void display_stats(const dimensions &, const tegrastats &); void update_usage_chart(std::vector> &, const std::vector &); diff --git a/utils.hh b/utils.hh index 71e7522..dbdef8e 100644 --- a/utils.hh +++ b/utils.hh @@ -10,17 +10,21 @@ #include #include -enum jetson_version {TK1, TX1, TX2}; +enum jetson_version {TK1, TX1, TX2, AGX}; struct tegrastats { - int mem_usage; - int mem_max; + int mem_usage = 0; + int mem_max = 0; std::vector cpu_usage; std::vector cpu_freq; - int gpu_usage; - int gpu_freq; + int gpu_usage = 0; + int gpu_freq = 0; + + int dla_power = 0; + int dla_power_avg = 0; + int dla_power_max = 0; jetson_version version; };