From 88394817c5a606f51fdfd29eb99678c8bec30439 Mon Sep 17 00:00:00 2001
From: Zach LaCelle <zlacelle@mitre.org>
Date: Mon, 23 Jul 2018 14:26:42 -0400
Subject: [PATCH] Updating gtop to use command-line arguments to specify the
 board type, not guess based on fields out of tegrastats. Added EMC plot.

---
 Makefile   |  3 ++
 display.cc |  5 ++++
 display.hh |  1 +
 gtop.cc    | 88 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 gtop.hh    |  3 +-
 utils.hh   |  3 ++
 6 files changed, 95 insertions(+), 8 deletions(-)

diff --git a/Makefile b/Makefile
index 861608c..80e92dd 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,9 @@
 all:
 	g++ -std=c++14 gtop.cc utils.cc display.cc -o gtop -pedantic -Wall -Wextra -lncurses -lpthread
 
+clean:
+	rm gtop
+
 fake:
 	g++ -std=c++14 gtop.cc utils.cc display.cc -o gtop -pedantic -Wall -Wextra -lncurses -lpthread -DTEGRASTATS_FAKE
 
diff --git a/display.cc b/display.cc
index a3da1fe..61a8130 100644
--- a/display.cc
+++ b/display.cc
@@ -121,6 +121,11 @@ void display_cpu_stats(const int & row, const tegrastats & ts) {
   }
 }
 
+void display_emc_stats(const int & row, const tegrastats & ts) {
+  mvprintw(row, 0, "EMC");
+  display_bars(row, BAR_OFFSET, ts.emc_usage, ts.emc_freq);
+}
+
 void display_gpu_stats(const int & row, const tegrastats & ts) {
   mvprintw(row, 0, "GPU");
   display_bars(row, BAR_OFFSET, ts.gpu_usage, ts.gpu_freq);
diff --git a/display.hh b/display.hh
index 9c68a8d..ed6d2f7 100644
--- a/display.hh
+++ b/display.hh
@@ -69,6 +69,7 @@ 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_mem_stats(const int &, const tegrastats &);
+void display_emc_stats(const int &, const tegrastats &);
 void display_usage_chart(const int &, const std::vector<std::vector<int>>);
 
 #endif // DISPLAY_HH_
diff --git a/gtop.cc b/gtop.cc
index d511ebc..d43a0cd 100644
--- a/gtop.cc
+++ b/gtop.cc
@@ -1,22 +1,62 @@
 // Martin Kersner, m.kersner@gmail.com
 // 2017/04/21
+// Modified by Zach LaCelle, zlacelle@gmail.com
+// 2018/07/23
 
 #include "gtop.hh"
+#include <getopt.h>
+#include <string>
 
 std::mutex m;
 std::condition_variable cv;
 tegrastats t_stats;
+std::string JETSON_TYPE="";
 
 bool processed = false;
 bool ready     = false;
 bool finished  = false;
 
-int main() {	
+int main(int argc, char** argv) {	
   if (getuid()) {
     std::cout << "gtop requires root privileges!" << std::endl;
     exit(1);
   }
 
+  //Get options
+  const char* short_opts = "21k";
+  static struct option long_options[] =
+  {
+    {"tx2", no_argument, nullptr, '2'},
+    {"tx1", no_argument, nullptr, '1'},
+    {"tk1", no_argument, nullptr, 'k'},
+    {nullptr, no_argument, nullptr, 0}
+  };
+
+  const auto opt = getopt_long(argc, argv, short_opts, long_options, nullptr);
+  switch(opt)
+  {
+    case '2':
+    {
+      JETSON_TYPE="TX2";
+      break;
+    }
+    case '1':
+    {
+      JETSON_TYPE="TX1";
+      break;
+    }
+    case 'k':
+    {
+      JETSON_TYPE="TK1";
+      break;
+    }
+    default:
+    {
+      printf("ERROR: Must define board type (either --tx2 --tx1, or --tk1)!\n");
+      exit(-1);
+    }
+  }
+  
   std::thread t(read_tegrastats); 
 
   initscr();
@@ -115,11 +155,19 @@ void read_tegrastats() {
 tegrastats parse_tegrastats(const char * buffer) {
   tegrastats ts;
   auto stats = tokenize(buffer, ' ');
-
-  if (stats.size() >= 15)
+  
+  if( JETSON_TYPE.compare("TX2") == 0 )
+  {
+    ts.version = TX2;
+  }
+  else if( JETSON_TYPE.compare("TX1") == 0 )
+  {
     ts.version = TX1;
+  }
   else
-    ts.version = TX2;
+  {
+    ts.version = TK1;
+  }
 
   get_mem_stats(ts, stats.at(1));
 
@@ -130,7 +178,21 @@ tegrastats parse_tegrastats(const char * buffer) {
       break;
     case TX2:
       get_cpu_stats_tx2(ts, stats.at(5));
-      get_gpu_stats(ts, stats.at(13));
+      //Test for newer TX2 format
+      if( stats.at(8) == "GR3D_FREQ" )
+      {
+	//New format
+	get_gpu_stats(ts, stats.at(9));
+      }
+      else
+      {
+	//Old format
+	get_gpu_stats(ts, stats.at(13));
+      }
+      if( stats.at(7) == "EMC_FREQ" )
+      {
+	get_emc_stats(ts, stats.at(8));
+      }
       break;
     case TK1: // TODO
       break;
@@ -139,6 +201,15 @@ tegrastats parse_tegrastats(const char * buffer) {
   return ts;
 }
 
+void get_emc_stats(tegrastats & ts, const std::string & str)
+{
+  auto emc_stats = tokenize(str, '@');
+  auto emc_usage = emc_stats.at(0);
+  
+  ts.emc_usage = std::stoi(emc_usage.substr(0, emc_usage.size()-1));
+  ts.emc_freq = std::stoi(emc_stats.at(1));
+}
+
 void get_cpu_stats_tx1(tegrastats & ts, const std::string & str) {
   auto cpu_stats = tokenize(str, '@');
   auto cpu_usage_all = cpu_stats.at(0);
@@ -192,12 +263,15 @@ void get_mem_stats(tegrastats & ts, const std::string & str) {
 void display_stats(const dimensions & d, const tegrastats & ts) {
   // CPU
   display_cpu_stats(0, ts);
-
+  
   // GPU
   display_gpu_stats(ts.cpu_usage.size(), ts);
 
   // Memory
-  display_mem_stats(ts.cpu_usage.size()+1, ts);
+  display_mem_stats(1 + ts.cpu_usage.size(), ts);
+
+  // EMC
+  display_emc_stats(2 + ts.cpu_usage.size(), ts);
 }
 
 void update_usage_chart(std::vector<std::vector<int>> & usage_buffer,
diff --git a/gtop.hh b/gtop.hh
index f601067..c6dd14e 100644
--- a/gtop.hh
+++ b/gtop.hh
@@ -21,7 +21,7 @@
 #include "display.hh"
 #include "utils.hh"
 
-const int STATS_BUFFER_SIZE = 256;
+const int STATS_BUFFER_SIZE = 1024;
 
 const std::string TEGRASTATS_PATH     = "~/tegrastats";
 const std::string TEGRASTATSFAKE_PATH = "./tegrastats_fake";
@@ -33,6 +33,7 @@ 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_emc_stats(tegrastats &, const std::string &);
 
 void display_stats(const dimensions &, const tegrastats &);
 void update_usage_chart(std::vector<std::vector<int>> &, const std::vector<int> &);
diff --git a/utils.hh b/utils.hh
index 71e7522..8b87b7c 100644
--- a/utils.hh
+++ b/utils.hh
@@ -22,6 +22,9 @@ struct tegrastats {
   int gpu_usage;
   int gpu_freq;
 
+  int emc_usage;
+  int emc_freq;
+  
   jetson_version version;
 };