diff mbox series

[v3,2/3] kernel-shark: Add command line options for selecting plots to be shown

Message ID 20200508152302.27843-3-y.karadz@gmail.com (mailing list archive)
State Accepted
Commit 80aea3b863141754ad488d34e40ac356f0f0fa51
Delegated to: Steven Rostedt
Headers show
Series [v3,1/3] kernel-shark: Add methods for selecting the plots to be shown | expand

Commit Message

Yordan Karadzhov May 8, 2020, 3:23 p.m. UTC
Example:
  kernelshark -i mytrace.dat --cpu '1,4-7' --pid 11

This will show CPUs: 1, 4, 5, 6, 7 and task(PID): 11.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
Suggested-by: Julia Lawall  <julia.lawall@inria.fr>
---
 kernel-shark/src/KsUtils.cpp     | 24 +++++++++++++++++++
 kernel-shark/src/KsUtils.hpp     |  2 ++
 kernel-shark/src/kernelshark.cpp | 41 +++++++++++++++++++++++++++++---
 3 files changed, 64 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/kernel-shark/src/KsUtils.cpp b/kernel-shark/src/KsUtils.cpp
index 77d0c7c..8c61b3f 100644
--- a/kernel-shark/src/KsUtils.cpp
+++ b/kernel-shark/src/KsUtils.cpp
@@ -336,6 +336,30 @@  QStringList splitArguments(QString cmd)
 	return argv;
 }
 
+/** Parse a string containing Ids. The string can be of the form "1 4-7 9". */
+QVector<int> parseIdList(QString v_str)
+{
+	QStringList list = v_str.split(",", QString::SkipEmptyParts);
+	QVector<int> v;
+
+	for (auto item: list) {
+		int i = item.indexOf('-');
+		if (i > 0) {
+			/* This item is an interval. */
+			int to = item.right(item.size() - i - 1).toInt();
+			int from = item.left(i).toInt();
+			int s = v.size();
+
+			v.resize(s + to - from + 1);
+			std::iota(v.begin() + s, v.end(), from);
+		} else {
+			v.append(item.toInt());
+		}
+	}
+
+	return v;
+}
+
 }; // KsUtils
 
 /** A stream operator for converting QColor into KsPlot::Color. */
diff --git a/kernel-shark/src/KsUtils.hpp b/kernel-shark/src/KsUtils.hpp
index f44139b..8293e7d 100644
--- a/kernel-shark/src/KsUtils.hpp
+++ b/kernel-shark/src/KsUtils.hpp
@@ -136,6 +136,8 @@  QString getSaveFile(QWidget *parent,
 
 QStringList splitArguments(QString cmd);
 
+QVector<int> parseIdList(QString v_str);
+
 }; // KsUtils
 
 /** Identifier of the Dual Marker active state. */
diff --git a/kernel-shark/src/kernelshark.cpp b/kernel-shark/src/kernelshark.cpp
index 1ec6678..0de80af 100644
--- a/kernel-shark/src/kernelshark.cpp
+++ b/kernel-shark/src/kernelshark.cpp
@@ -29,20 +29,43 @@  void usage(const char *prog)
 	printf("  -u	unregister plugin, use plugin name or absolute path\n");
 	printf("  -s	import a session\n");
 	printf("  -l	import the last session\n");
+	puts(" --cpu	show plots for CPU cores, default is \"show all\"");
+	puts(" --pid	show plots for tasks, default is \"do not show\"");
+	puts("\n example:");
+	puts("  kernelshark -i mytrace.dat --cpu 1,4-7 --pid 11 -p path/to/my/plugin/myplugin.so\n");
 }
 
+#define KS_LONG_OPTS 0
+static option longOptions[] = {
+	{"help", no_argument, nullptr, 'h'},
+	{"pid", required_argument, nullptr, KS_LONG_OPTS},
+	{"cpu", required_argument, nullptr, KS_LONG_OPTS},
+	{nullptr, 0, nullptr, 0}
+};
+
 int main(int argc, char **argv)
 {
 	QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
 	QApplication a(argc, argv);
 
+	QVector<int> cpuPlots, taskPlots;
+	bool fromSession = false;
+	int optionIndex = 0;
 	KsMainWindow ks;
-
 	int c;
-	bool fromSession = false;
 
-	while ((c = getopt(argc, argv, "hvi:p:u:s:l")) != -1) {
+	while ((c = getopt_long(argc, argv, "hvi:p:u:s:l",
+					    longOptions,
+					    &optionIndex)) != -1) {
 		switch(c) {
+		case KS_LONG_OPTS:
+			if (strcmp(longOptions[optionIndex].name, "cpu") == 0)
+				cpuPlots.append(KsUtils::parseIdList(QString(optarg)));
+			else if (strcmp(longOptions[optionIndex].name, "pid") == 0)
+				taskPlots.append(KsUtils::parseIdList(QString(optarg)));
+
+			break;
+
 		case 'h':
 			usage(argv[0]);
 			return 0;
@@ -95,6 +118,18 @@  int main(int argc, char **argv)
 			ks.loadDataFile(QString(input_file));
 	}
 
+	auto lamOrderIds = [] (QVector<int> &ids) {
+		/* Sort and erase duplicates. */
+		std::sort(ids.begin(), ids.end());
+		ids.erase(std::unique(ids.begin(), ids.end()), ids.end());
+		return ids;
+	};
+
+	if (cpuPlots.count() || taskPlots.count()) {
+		ks.setCPUPlots(lamOrderIds(cpuPlots));
+		ks.setTaskPlots(lamOrderIds(taskPlots));
+	}
+
 	ks.show();
 	return a.exec();
 }