Build-Depends: ninja-build, meson (>=0.50), debhelper (>=9),
gcc-9 | gcc-8 | gcc-7 | gcc-6 | gcc-5, libgtest-dev, python,
libiniparser-dev, pkg-config, cmake, libdrm-dev,
- linux-fvp-headers, libmrpsim-dev, libtinyxml2-dev
+ linux-fvp-headers, libmrpsim-dev, libtinyxml2-dev, libncurses-dev
Standards-Version: 3.8.2
Homepage: https://research.samsung.com
Package: npu-engine-utils
Architecture: amd64
Multi-Arch: same
-Depends: npu-engine, ${shlibs:Depends}, ${misc:Depends}
+Depends: npu-engine, libncurses5, ${shlibs:Depends}, ${misc:Depends}
Description: NPU Engine Utils Package
This provides utility packages for NPU Engine, including metadata extraction of model files.
#include <unistd.h>
#include <errno.h>
+#include <ncurses.h>
+#include <signal.h>
+#include <getopt.h>
+
using namespace std;
+static struct option longopts[] = {
+ {"help", no_argument, 0, 'h'},
+ {"device-node", optional_argument, 0, 'd'},
+ {"app-id", optional_argument, 0, 'a'},
+ {"interval", optional_argument, 0, 'i'},
+ {0, 0, 0, 0}
+};
+
/** @brief Class of Trinity SMI (Trinity System Management Interface) */
class TrinitySMI {
public:
- TrinitySMI (const char *name) {
- const char * last = strrchr (name, '/');
- if (last != NULL) {
- name_ = string (last + 1);
- } else {
- name_ = string (name);
- }
- }
+ TrinitySMI () : help_only_ (false) {}
~TrinitySMI () {}
- bool check_arguments (int argc, char ** argv);
+ void parse_arguments (int argc, char ** argv);
+ void check_arguments (int argc, char ** argv);
void append_version ();
void append_stats ();
- void dump ();
+ void dump (bool use_curses);
+ int loop ();
void set_device (string node) { node_ = node; }
void set_appid (string appid) { appid_ = appid; }
+ void set_interval (string interval) { interval_ = interval; }
private:
uint32_t get_api_level ();
string name_;
stringstream ss_;
+ string help_msg_;
+ bool help_only_;
+
string appid_;
string node_;
+ string interval_;
};
/** @brief get driver api level from any device */
void
TrinitySMI::append_help ()
{
+ ss_ << help_msg_;
ss_ << "\nUsage: " << name_ << " [options]\n";
ss_ << "Options:\n";
- ss_ << " -h \t\tShow help messages\n";
- ss_ << " -d [dev node] Specify a device node that you're interested in\n";
- ss_ << "\t\t(e.g., -d triv2-0)\n";
- ss_ << " -a [app id] \tSpecify a app id that you're interested in\n";
- ss_ << "\t\t(e.g., -d triv2-0 -a 125)\n";
+ ss_ << " -h, --help\t\t\tShow help messages\n";
+ ss_ << " -d, --device-node=<node>\tDevice node that you're interested in\n";
+ ss_ << "\t\t\t\t(e.g., -d /dev/triv2-0)\n";
+ ss_ << " -a, --app-id=<id>\t\tApp id that you're interested in\n";
+ ss_ << "\t\t\t\t(e.g., -d /dev/triv2-0 -a 125)\n";
+ ss_ << " -i, --interval=<secs>\t\tInterval in seconds to wait between updates\n";
+ ss_ << "\t\t\t\t(e.g., -i 1)\n";
+}
+
+/** @brief show the appended string to screen */
+void
+TrinitySMI::dump (bool use_curses)
+{
+ string s = ss_.str ();
+
+ if (use_curses)
+ mvaddstr (0, 0, s.c_str ());
+ else
+ cout << s;
+
+ ss_.str ("");
+}
+
+static uint32_t
+get_interval (const char * interval_str)
+{
+ char *endptr;
+ unsigned long interval = 0;
+
+ if (interval_str) {
+ errno = 0;
+ interval = strtoul (interval_str, &endptr, 10);
+ if (errno != 0 || interval_str == endptr)
+ interval = 0;
+ }
+
+ return interval;
+}
+
+static void do_exit(int status)
+{
+ endwin();
+ exit(status);
+}
+
+static void die(int notused)
+{
+ (void) notused;
+ do_exit(0);
+}
+
+int
+TrinitySMI::loop ()
+{
+ uint32_t interval = get_interval (interval_.c_str ());
+ bool use_curses = (interval != 0 && !help_only_);
+
+ if (use_curses) {
+ signal (SIGINT, die);
+ signal (SIGTERM, die);
+ signal (SIGHUP, die);
+
+ initscr ();
+ nonl ();
+ noecho ();
+ cbreak ();
+ }
+
+ do {
+ clear ();
+
+ append_version ();
+ if (help_only_)
+ append_help ();
+ else
+ append_stats ();
+ dump (use_curses);
+
+ refresh();
+
+ if (interval != 0)
+ sleep (interval);
+
+ } while (use_curses);
+
+ if (use_curses)
+ endwin();
+
+ return 0;
}
/** @brief check the given arguments */
-bool
+void
TrinitySMI::check_arguments (int argc, char ** argv)
{
int c;
optind = 0;
opterr = 0;
- while ((c = getopt (argc, argv, "hd:a:")) != -1) {
+ while ((c = getopt_long (argc, argv, "hd:a:i:", longopts, (int *) 0)) != EOF) {
switch (c) {
case 'd':
set_device (optarg);
case 'a':
set_appid (optarg);
break;
+ case 'i':
+ set_interval (optarg);
+ break;
case '?':
if (optopt == 'd')
- ss_ << "\nOption '-d' requires an extra argument\n";
+ help_msg_ = "\nOption '-d' requires an extra argument\n";
else if (optopt == 'a')
- ss_ << "\nOption '-a' requires an extra argument\n";
+ help_msg_ = "\nOption '-a' requires an extra argument\n";
+ else if (optopt == 'i')
+ help_msg_ = "\nOption '-i' requires an extra argument\n";
else
- ss_ << "\nUnknown flag detected: " << (char) optopt << "\n";
+ help_msg_ = "\nUnknown flag detected: " + to_string ((char) optopt) + "\n";
// no-break
case 'h':
- append_help ();
- return false;
+ help_only_ = true;
+ break;
}
}
if (!appid_.empty () && node_.empty ()) {
- ss_ << "\nOption '-a' requires Option '-d' as well, to specify a device node\n";
- append_help ();
- return false;
+ help_msg_ = "\nOption '-a' requires Option '-d' as well, to specify a device node\n";
+ help_only_ = true;
}
-
- return true;
}
-/** @brief show the appended string to screen */
void
-TrinitySMI::dump ()
+TrinitySMI::parse_arguments (int argc, char ** argv)
{
- cout << ss_.str ();
+ char * name = argv[0];
+ const char * last = strrchr (name, '/');
+
+ if (last != NULL) {
+ name_ = string (last + 1);
+ } else {
+ name_ = string (name);
+ }
+
+ check_arguments (argc, argv);
}
/** @brief main routine of trinity-smi */
int main (int argc, char **argv)
{
- TrinitySMI smi (argv[0]);
+ TrinitySMI smi;
- smi.append_version ();
- if (smi.check_arguments (argc, argv))
- smi.append_stats ();
- smi.dump ();
+ smi.parse_arguments (argc, argv);
- return 0;
+ return smi.loop ();
}