linux-trace-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/17] More modifications and bug fixes toward KS 1.0
@ 2018-11-28 15:16 Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 01/17] kernel-shark-qt: Updata Event filter mask when applaing filters to Graph Yordan Karadzhov
                   ` (16 more replies)
  0 siblings, 17 replies; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

This series of patches continues adding various unrelated modifications
and bug fixes needed before releasing KernelShark 1.0. Some of the patches
from the previous series, which for various reasons didn't manage to move
upstream are sent again here.


Yordan Karadzhov (17):
  kernel-shark-qt: Updata Event filter mask when applaing filters to
    Graph
  kernel-shark-qt: Reprocess all CPU collections when the filtering
    changes
  kernel-shark-qt: Fix a byg in unset_event_filter_flag()
  kernel-shark qt: No error when Record authentication dialog is closed
  kernel-shark-qt: Protect all calls of tep_read_number_field()
  kernel-shark-qt: Ignore sched_wakeup events if the task is running.
  kernel-shark-qt: Fix the documentation of libkshark-model
  kernel-shark-qt: Add a method for easy retrieve of all Ids of a filter
  kernel-shark-qt: Add centralized context menu for View and Graph
    widgets
  kernel-shark-qt: Add keyboard shortcuts for deselecting the marker
  kernel-shark-qt: Sort all graphs before plotting
  kernel-shark-qt: Add CPU-based filtering to the C API
  kernel-shark-qt: Add CPU-based filtering to KsDataStore
  kernel-shark-qt: Add Hide CPU action to the Quick Context Menu
  kernel-shark-qt: Add the CPU filters to the Json config I/O
  kernel-shark-qt: Add "Hide CPU" checkbox dialog to the Main window
    menu
  kernel-shark-qt: Add the user filter mask to the Json config I/O

 kernel-shark-qt/src/CMakeLists.txt          |   2 +
 kernel-shark-qt/src/KsGLWidget.cpp          |  46 +--
 kernel-shark-qt/src/KsGLWidget.hpp          |  22 +-
 kernel-shark-qt/src/KsMainWindow.cpp        | 117 +++++++-
 kernel-shark-qt/src/KsMainWindow.hpp        |  14 +
 kernel-shark-qt/src/KsQuickContextMenu.cpp  | 302 ++++++++++++++++++++
 kernel-shark-qt/src/KsQuickContextMenu.hpp  | 142 +++++++++
 kernel-shark-qt/src/KsTraceGraph.cpp        |  96 +++++++
 kernel-shark-qt/src/KsTraceGraph.hpp        |  14 +
 kernel-shark-qt/src/KsTraceViewer.cpp       |  30 +-
 kernel-shark-qt/src/KsTraceViewer.hpp       |  32 ++-
 kernel-shark-qt/src/KsUtils.cpp             |  48 +++-
 kernel-shark-qt/src/KsUtils.hpp             |   6 +
 kernel-shark-qt/src/KsWidgetsLib.cpp        | 120 --------
 kernel-shark-qt/src/KsWidgetsLib.hpp        |  44 ---
 kernel-shark-qt/src/libkshark-configio.c    | 232 ++++++++++++---
 kernel-shark-qt/src/libkshark-model.c       |   4 +-
 kernel-shark-qt/src/libkshark.c             |  48 +++-
 kernel-shark-qt/src/libkshark.h             |  56 +++-
 kernel-shark-qt/src/plugins/SchedEvents.cpp |  15 +
 kernel-shark-qt/src/plugins/sched_events.c  |  52 ++--
 21 files changed, 1149 insertions(+), 293 deletions(-)
 create mode 100644 kernel-shark-qt/src/KsQuickContextMenu.cpp
 create mode 100644 kernel-shark-qt/src/KsQuickContextMenu.hpp

-- 
2.17.1

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 01/17] kernel-shark-qt: Updata Event filter mask when applaing filters to Graph
  2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
@ 2018-11-28 15:16 ` Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 02/17] kernel-shark-qt: Reprocess all CPU collections when the filtering changes Yordan Karadzhov
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

KS_GRAPH_VIEW_FILTER_MASK and KS_EVENT_VIEW_FILTER_MASK are two bit
flags used to control the visibility of an entry inside the Graphs.
Both flags have to be updated when the "Apply filters to Graph"
checkbox is clicked.

Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
 kernel-shark-qt/src/KsUtils.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel-shark-qt/src/KsUtils.cpp b/kernel-shark-qt/src/KsUtils.cpp
index 5e4c9c8..8bb0970 100644
--- a/kernel-shark-qt/src/KsUtils.cpp
+++ b/kernel-shark-qt/src/KsUtils.cpp
@@ -67,8 +67,10 @@ void graphFilterSync(bool state)
 
 	if (state) {
 		kshark_ctx->filter_mask |= KS_GRAPH_VIEW_FILTER_MASK;
+		kshark_ctx->filter_mask |= KS_EVENT_VIEW_FILTER_MASK;
 	} else {
 		kshark_ctx->filter_mask &= ~KS_GRAPH_VIEW_FILTER_MASK;
+		kshark_ctx->filter_mask &= ~KS_EVENT_VIEW_FILTER_MASK;
 	}
 }
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 02/17] kernel-shark-qt: Reprocess all CPU collections when the filtering changes
  2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 01/17] kernel-shark-qt: Updata Event filter mask when applaing filters to Graph Yordan Karadzhov
@ 2018-11-28 15:16 ` Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 03/17] kernel-shark-qt: Fix a byg in unset_event_filter_flag() Yordan Karadzhov
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

The CPU data collections are processed according to the visibility of
the entries. If the filtering condition changes, we need to reprocess
those data collections.

Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
 kernel-shark-qt/src/KsUtils.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/kernel-shark-qt/src/KsUtils.cpp b/kernel-shark-qt/src/KsUtils.cpp
index 8bb0970..25e7fdb 100644
--- a/kernel-shark-qt/src/KsUtils.cpp
+++ b/kernel-shark-qt/src/KsUtils.cpp
@@ -186,10 +186,14 @@ void KsDataStore::update()
 	if (!kshark_instance(&kshark_ctx))
 		return;
 
+	_unregisterCPUCollections();
+
 	if (kshark_filter_is_set(kshark_ctx)) {
 		kshark_filter_entries(kshark_ctx, _rows, _dataSize);
 		emit updateWidgets(this);
 	}
+
+	registerCPUCollections();
 }
 
 /** Register a collection of visible entries for each CPU. */
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 03/17] kernel-shark-qt: Fix a byg in unset_event_filter_flag()
  2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 01/17] kernel-shark-qt: Updata Event filter mask when applaing filters to Graph Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 02/17] kernel-shark-qt: Reprocess all CPU collections when the filtering changes Yordan Karadzhov
@ 2018-11-28 15:16 ` Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 04/17] kernel-shark qt: No error when Record authentication dialog is closed Yordan Karadzhov
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

Currently the unset_event_filter_flag() function unsets explicitly the
EVENT_VIEW visibility flag, ignoring the user's request for visibility
of the data after the filtering. This is wrong. The value of the
coresponging bit in the user-provided mask (kshark_ctx->filter_mask),
has to be used instead.

Since the function becames very simple now it is declared as inline.

Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
 kernel-shark-qt/src/libkshark.c | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/kernel-shark-qt/src/libkshark.c b/kernel-shark-qt/src/libkshark.c
index fa85171..b4b3d5b 100644
--- a/kernel-shark-qt/src/libkshark.c
+++ b/kernel-shark-qt/src/libkshark.c
@@ -448,19 +448,18 @@ bool kshark_filter_is_set(struct kshark_context *kshark_ctx)
 	       filter_is_set(kshark_ctx->hide_event_filter);
 }
 
-static void unset_event_filter_flag(struct kshark_context *kshark_ctx,
-				    struct kshark_entry *e)
+static inline void unset_event_filter_flag(struct kshark_context *kshark_ctx,
+					   struct kshark_entry *e)
 {
 	/*
 	 * All entries, filtered-out by the event filters, will be treated
 	 * differently, when visualized. Because of this, ignore the value
 	 * of the GRAPH_VIEW flag provided by the user via
-	 * kshark_ctx->filter_mask and unset the EVENT_VIEW flag.
+	 * kshark_ctx->filter_mask. The value of the EVENT_VIEW flag in
+	 * kshark_ctx->filter_mask will be used instead.
 	 */
-	int event_mask = kshark_ctx->filter_mask;
+	int event_mask = kshark_ctx->filter_mask & ~KS_GRAPH_VIEW_FILTER_MASK;
 
-	event_mask &= ~KS_GRAPH_VIEW_FILTER_MASK;
-	event_mask |= KS_EVENT_VIEW_FILTER_MASK;
 	e->visible &= ~event_mask;
 }
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 04/17] kernel-shark qt: No error when Record authentication dialog is closed
  2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
                   ` (2 preceding siblings ...)
  2018-11-28 15:16 ` [PATCH 03/17] kernel-shark-qt: Fix a byg in unset_event_filter_flag() Yordan Karadzhov
@ 2018-11-28 15:16 ` Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 05/17] kernel-shark-qt: Protect all calls of tep_read_number_field() Yordan Karadzhov
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

No error message must be shown in the case when the user dismissed
the authentication dialog (clicked Cancel).

Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
 kernel-shark-qt/src/KsMainWindow.cpp | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/kernel-shark-qt/src/KsMainWindow.cpp b/kernel-shark-qt/src/KsMainWindow.cpp
index ffb10d4..8e8484f 100644
--- a/kernel-shark-qt/src/KsMainWindow.cpp
+++ b/kernel-shark-qt/src/KsMainWindow.cpp
@@ -959,13 +959,28 @@ void KsMainWindow::_captureStarted()
 	_captureLocalServer.listen("KSCapture");
 }
 
-void KsMainWindow::_captureFinished(int exit, QProcess::ExitStatus st)
+/**
+ * If the authorization could not be obtained because the user dismissed
+ * the authentication dialog (clicked Cancel), pkexec exits with a return
+ * value of 126.
+ */
+#define PKEXEC_DISMISS_RET	126
+
+void KsMainWindow::_captureFinished(int ret, QProcess::ExitStatus st)
 {
 	QProcess *capture = (QProcess *)sender();
 
 	_captureLocalServer.close();
 
-	if (exit != 0 || st != QProcess::NormalExit) {
+	if (ret == PKEXEC_DISMISS_RET) {
+		/*
+		 * Authorization could not be obtained because the user
+		 * dismissed the authentication dialog.
+		 */
+		return;
+	}
+
+	if (ret != 0 || st != QProcess::NormalExit) {
 		QString message = "Capture process failed:<br>";
 
 		message += capture->errorString();
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 05/17] kernel-shark-qt: Protect all calls of tep_read_number_field()
  2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
                   ` (3 preceding siblings ...)
  2018-11-28 15:16 ` [PATCH 04/17] kernel-shark qt: No error when Record authentication dialog is closed Yordan Karadzhov
@ 2018-11-28 15:16 ` Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 06/17] kernel-shark-qt: Ignore sched_wakeup events if the task is running Yordan Karadzhov
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

tep_read_number_field() is being used to retrieve the value of a data
field and this value has being used without checking if the function
succeeded. This is a potential bug because tep_read_number_field() may
fail and in such a case the retrieved field value will be arbitrary.

Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
 kernel-shark-qt/src/plugins/sched_events.c | 52 +++++++++++++---------
 1 file changed, 30 insertions(+), 22 deletions(-)

diff --git a/kernel-shark-qt/src/plugins/sched_events.c b/kernel-shark-qt/src/plugins/sched_events.c
index 1851569..59ffcfe 100644
--- a/kernel-shark-qt/src/plugins/sched_events.c
+++ b/kernel-shark-qt/src/plugins/sched_events.c
@@ -97,10 +97,12 @@ int plugin_get_next_pid(struct tep_record *record)
 	struct plugin_sched_context *plugin_ctx =
 		plugin_sched_context_handler;
 	unsigned long long val;
+	int ret;
 
-	tep_read_number_field(plugin_ctx->sched_switch_next_field,
-			      record->data, &val);
-	return val;
+	ret = tep_read_number_field(plugin_ctx->sched_switch_next_field,
+				    record->data, &val);
+
+	return ret ? : val;
 }
 
 /**
@@ -113,10 +115,12 @@ int plugin_get_rec_wakeup_pid(struct tep_record *record)
 	struct plugin_sched_context *plugin_ctx =
 		plugin_sched_context_handler;
 	unsigned long long val;
+	int ret;
+
+	ret = tep_read_number_field(plugin_ctx->sched_wakeup_pid_field,
+				    record->data, &val);
 
-	tep_read_number_field(plugin_ctx->sched_wakeup_pid_field,
-			      record->data, &val);
-	return val;
+	return ret ? : val;
 }
 
 static void plugin_register_command(struct kshark_context *kshark_ctx,
@@ -145,11 +149,12 @@ static int plugin_get_rec_wakeup_new_pid(struct tep_record *record)
 	struct plugin_sched_context *plugin_ctx =
 		plugin_sched_context_handler;
 	unsigned long long val;
+	int ret;
 
-	tep_read_number_field(plugin_ctx->sched_wakeup_new_pid_field,
-				 record->data, &val);
+	ret = tep_read_number_field(plugin_ctx->sched_wakeup_new_pid_field,
+				    record->data, &val);
 
-	return val;
+	return ret ? : val;
 }
 
 /**
@@ -170,7 +175,7 @@ bool plugin_wakeup_match_rec_pid(struct kshark_context *kshark_ctx,
 	struct plugin_sched_context *plugin_ctx;
 	struct tep_record *record = NULL;
 	unsigned long long val;
-	int wakeup_pid = -1;
+	int ret, wakeup_pid = -1;
 
 	plugin_ctx = plugin_sched_context_handler;
 	if (!plugin_ctx)
@@ -181,10 +186,10 @@ bool plugin_wakeup_match_rec_pid(struct kshark_context *kshark_ctx,
 		record = kshark_read_at(kshark_ctx, e->offset);
 
 		/* We only want those that actually woke up the task. */
-		tep_read_number_field(plugin_ctx->sched_wakeup_success_field,
-				      record->data, &val);
+		ret = tep_read_number_field(plugin_ctx->sched_wakeup_success_field,
+					    record->data, &val);
 
-		if (val)
+		if (ret == 0 && val)
 			wakeup_pid = plugin_get_rec_wakeup_pid(record);
 	}
 
@@ -193,10 +198,10 @@ bool plugin_wakeup_match_rec_pid(struct kshark_context *kshark_ctx,
 		record = kshark_read_at(kshark_ctx, e->offset);
 
 		/* We only want those that actually woke up the task. */
-		tep_read_number_field(plugin_ctx->sched_wakeup_new_success_field,
-				      record->data, &val);
+		ret = tep_read_number_field(plugin_ctx->sched_wakeup_new_success_field,
+					    record->data, &val);
 
-		if (val)
+		if (ret == 0 && val)
 			wakeup_pid = plugin_get_rec_wakeup_new_pid(record);
 	}
 
@@ -224,7 +229,7 @@ bool plugin_switch_match_rec_pid(struct kshark_context *kshark_ctx,
 {
 	struct plugin_sched_context *plugin_ctx;
 	unsigned long long val;
-	int switch_pid = -1;
+	int ret, switch_pid = -1;
 
 	plugin_ctx = plugin_sched_context_handler;
 
@@ -233,10 +238,10 @@ bool plugin_switch_match_rec_pid(struct kshark_context *kshark_ctx,
 		struct tep_record *record;
 
 		record = kshark_read_at(kshark_ctx, e->offset);
-		tep_read_number_field(plugin_ctx->sched_switch_prev_state_field,
-				      record->data, &val);
+		ret = tep_read_number_field(plugin_ctx->sched_switch_prev_state_field,
+					    record->data, &val);
 
-		if (!(val & 0x7f))
+		if (ret == 0 && !(val & 0x7f))
 			switch_pid = tep_data_pid(plugin_ctx->pevent, record);
 
 		free_record(record);
@@ -278,8 +283,11 @@ static void plugin_sched_action(struct kshark_context *kshark_ctx,
 				struct tep_record *rec,
 				struct kshark_entry *entry)
 {
-	entry->pid = plugin_get_next_pid(rec);
-	plugin_register_command(kshark_ctx, rec, entry->pid);
+	int pid = plugin_get_next_pid(rec);
+	if (pid >= 0) {
+		entry->pid = pid;
+		plugin_register_command(kshark_ctx, rec, entry->pid);
+	}
 }
 
 static int plugin_sched_init(struct kshark_context *kshark_ctx)
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 06/17] kernel-shark-qt: Ignore sched_wakeup events if the task is running.
  2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
                   ` (4 preceding siblings ...)
  2018-11-28 15:16 ` [PATCH 05/17] kernel-shark-qt: Protect all calls of tep_read_number_field() Yordan Karadzhov
@ 2018-11-28 15:16 ` Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 07/17] kernel-shark-qt: Fix the documentation of libkshark-model Yordan Karadzhov
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

The "Sched Events" plugin uses the sched_wakeup events to visualize
the wake up latency of the task. This patch deals with the corner
case, when we have a second sched_wakeup events which tries to wake
up a task which is already running.

Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
 kernel-shark-qt/src/plugins/SchedEvents.cpp | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/kernel-shark-qt/src/plugins/SchedEvents.cpp b/kernel-shark-qt/src/plugins/SchedEvents.cpp
index b4596c9..ea07662 100644
--- a/kernel-shark-qt/src/plugins/SchedEvents.cpp
+++ b/kernel-shark-qt/src/plugins/SchedEvents.cpp
@@ -139,6 +139,21 @@ static void pluginDraw(plugin_sched_context *plugin_ctx,
 				ksmodel_get_entry_back(histo, bin, false,
 						       plugin_wakeup_match_rec_pid,
 						       pid, col, &indexOpen);
+
+			if (entryOpen) {
+				int cpu = ksmodel_get_cpu_back(histo, bin,
+								      pid,
+								      false,
+								      col,
+								      nullptr);
+				if (cpu >= 0) {
+					/*
+					 * The task is already running. Ignore
+					 * this wakeup event.
+					 */
+					entryOpen = nullptr;
+				}
+			}
 		}
 
 		if (rec) {
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 07/17] kernel-shark-qt: Fix the documentation of libkshark-model
  2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
                   ` (5 preceding siblings ...)
  2018-11-28 15:16 ` [PATCH 06/17] kernel-shark-qt: Ignore sched_wakeup events if the task is running Yordan Karadzhov
@ 2018-11-28 15:16 ` Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 08/17] kernel-shark-qt: Add a method for easy retrieve of all Ids of a filter Yordan Karadzhov
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

This patch fixes a simple copy/paste mistake in the Doxygen
documentation of the ksmodel_get_cpu_xxx() functions.

Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
 kernel-shark-qt/src/libkshark-model.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel-shark-qt/src/libkshark-model.c b/kernel-shark-qt/src/libkshark-model.c
index 461f88e..76e2940 100644
--- a/kernel-shark-qt/src/libkshark-model.c
+++ b/kernel-shark-qt/src/libkshark-model.c
@@ -1070,7 +1070,7 @@ static int ksmodel_get_entry_cpu(const struct kshark_entry *entry)
  * @param index: Optional output location for the index of the requested
  *		 entry inside the array.
  *
- * @returns Process Id of the task if an entry has been found. Else a negative
+ * @returns The CPU Id of the task if an entry has been found. Else a negative
  *	    Identifier (KS_EMPTY_BIN or KS_FILTERED_BIN).
  */
 int ksmodel_get_cpu_front(struct kshark_trace_histo *histo,
@@ -1103,7 +1103,7 @@ int ksmodel_get_cpu_front(struct kshark_trace_histo *histo,
  * @param index: Optional output location for the index of the requested
  *		 entry inside the array.
  *
- * @returns Process Id of the task if an entry has been found. Else a negative
+ * @returns The CPU Id of the task if an entry has been found. Else a negative
  *	    Identifier (KS_EMPTY_BIN or KS_FILTERED_BIN).
  */
 int ksmodel_get_cpu_back(struct kshark_trace_histo *histo,
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 08/17] kernel-shark-qt: Add a method for easy retrieve of all Ids of a filter
  2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
                   ` (6 preceding siblings ...)
  2018-11-28 15:16 ` [PATCH 07/17] kernel-shark-qt: Fix the documentation of libkshark-model Yordan Karadzhov
@ 2018-11-28 15:16 ` Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 09/17] kernel-shark-qt: Add centralized context menu for View and Graph widgets Yordan Karadzhov
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

This patch adds to KsUtils a method which can be used to retrieve
a vector of sorted Id values associated with a given filter.
The method will be used by the Quick Context Menu widget.

Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
 kernel-shark-qt/src/KsUtils.cpp | 21 +++++++++++++++++++++
 kernel-shark-qt/src/KsUtils.hpp |  2 ++
 2 files changed, 23 insertions(+)

diff --git a/kernel-shark-qt/src/KsUtils.cpp b/kernel-shark-qt/src/KsUtils.cpp
index 25e7fdb..c0e0f7d 100644
--- a/kernel-shark-qt/src/KsUtils.cpp
+++ b/kernel-shark-qt/src/KsUtils.cpp
@@ -36,6 +36,27 @@ QVector<int> getPidList()
 	return pids;
 }
 
+/** @brief Get a sorted vector of Id values of a filter. */
+QVector<int> getFilterIds(tracecmd_filter_id *filter)
+{
+	kshark_context *kshark_ctx(nullptr);
+	int *cpuFilter, n;
+	QVector<int> v;
+
+	if (!kshark_instance(&kshark_ctx))
+		return v;
+
+	cpuFilter = tracecmd_filter_ids(filter);
+	n = filter->count;
+	for (int i = 0; i < n; ++i)
+		v.append(cpuFilter[i]);
+
+	qSort(v);
+
+	free(cpuFilter);
+	return v;
+}
+
 /**
  * Set the bit of the filter mask of the kshark session context responsible
  * for the visibility of the events in the Table View.
diff --git a/kernel-shark-qt/src/KsUtils.hpp b/kernel-shark-qt/src/KsUtils.hpp
index b14cd6a..888ed56 100644
--- a/kernel-shark-qt/src/KsUtils.hpp
+++ b/kernel-shark-qt/src/KsUtils.hpp
@@ -84,6 +84,8 @@ namespace KsUtils {
 
 QVector<int> getPidList();
 
+QVector<int> getFilterIds(tracecmd_filter_id *filter);
+
 /** @brief Geat the list of plugins. */
 inline QStringList getPluginList() {return plugins.split(";");}
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 09/17] kernel-shark-qt: Add centralized context menu for View and Graph widgets
  2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
                   ` (7 preceding siblings ...)
  2018-11-28 15:16 ` [PATCH 08/17] kernel-shark-qt: Add a method for easy retrieve of all Ids of a filter Yordan Karadzhov
@ 2018-11-28 15:16 ` Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 10/17] kernel-shark-qt: Add keyboard shortcuts for deselecting the marker Yordan Karadzhov
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

This patch redesigns the context menu, used so far by the View
(table) widget. The goal is to make this menu universal and to
make possible to open it from both View and Graph widgets. The
context menu gets open by a right mouse click. The problem here
was, that so far the right mouse click in the Graph widget was
used for deselecting the Active marker. Now the Active marker
can be unset via the menu.

Because the new design of the Context menu requires significant
modification of the flow of signals between the widgets, the
changes cannot be broken into smaller patches. Also the
implementation of the menu is more complex now (much more code),
hence its source code has been moved from KsWidgetsLib into
separate header and source files.

Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
 kernel-shark-qt/src/CMakeLists.txt         |   2 +
 kernel-shark-qt/src/KsGLWidget.cpp         |  46 ++--
 kernel-shark-qt/src/KsGLWidget.hpp         |  22 +-
 kernel-shark-qt/src/KsMainWindow.cpp       |  17 +-
 kernel-shark-qt/src/KsMainWindow.hpp       |   2 +
 kernel-shark-qt/src/KsQuickContextMenu.cpp | 274 +++++++++++++++++++++
 kernel-shark-qt/src/KsQuickContextMenu.hpp | 136 ++++++++++
 kernel-shark-qt/src/KsTraceGraph.cpp       |  94 +++++++
 kernel-shark-qt/src/KsTraceGraph.hpp       |  14 ++
 kernel-shark-qt/src/KsTraceViewer.cpp      |  30 ++-
 kernel-shark-qt/src/KsTraceViewer.hpp      |  32 ++-
 kernel-shark-qt/src/KsWidgetsLib.cpp       | 120 ---------
 kernel-shark-qt/src/KsWidgetsLib.hpp       |  44 ----
 13 files changed, 622 insertions(+), 211 deletions(-)
 create mode 100644 kernel-shark-qt/src/KsQuickContextMenu.cpp
 create mode 100644 kernel-shark-qt/src/KsQuickContextMenu.hpp

diff --git a/kernel-shark-qt/src/CMakeLists.txt b/kernel-shark-qt/src/CMakeLists.txt
index ef0aa71..3eddaed 100644
--- a/kernel-shark-qt/src/CMakeLists.txt
+++ b/kernel-shark-qt/src/CMakeLists.txt
@@ -40,6 +40,7 @@ if (Qt5Widgets_FOUND AND Qt5Network_FOUND)
                         KsTraceViewer.hpp
                         KsMainWindow.hpp
                         KsCaptureDialog.hpp
+                        KsQuickContextMenu.hpp
                         KsAdvFilteringDialog.hpp)
 
     QT5_WRAP_CPP(ks-guiLib_hdr_moc ${ks-guiLib_hdr})
@@ -54,6 +55,7 @@ if (Qt5Widgets_FOUND AND Qt5Network_FOUND)
                                                             KsTraceViewer.cpp
                                                             KsMainWindow.cpp
                                                             KsCaptureDialog.cpp
+                                                            KsQuickContextMenu.cpp
                                                             KsAdvFilteringDialog.cpp)
 
     target_link_libraries(kshark-gui kshark-plot
diff --git a/kernel-shark-qt/src/KsGLWidget.cpp b/kernel-shark-qt/src/KsGLWidget.cpp
index 2a0b16b..917e86d 100644
--- a/kernel-shark-qt/src/KsGLWidget.cpp
+++ b/kernel-shark-qt/src/KsGLWidget.cpp
@@ -115,11 +115,6 @@ void KsGLWidget::mousePressEvent(QMouseEvent *event)
 	if (event->button() == Qt::LeftButton) {
 		_posMousePress = _posInRange(event->pos().x());
 		_rangeBoundInit(_posMousePress);
-	} else if (event->button() == Qt::RightButton) {
-		emit deselect();
-		_mState->activeMarker().remove();
-		_mState->updateLabels();
-		_model.update();
 	}
 }
 
@@ -189,8 +184,8 @@ void KsGLWidget::mouseMoveEvent(QMouseEvent *event)
 		_rangeBoundStretched(_posInRange(event->pos().x()));
 
 	bin = event->pos().x() - _hMargin;
-	cpu = _getCPU(event->pos().y());
-	pid = _getPid(event->pos().y());
+	cpu = getPlotCPU(event->pos());
+	pid = getPlotPid(event->pos());
 
 	ret = _find(bin, cpu, pid, 5, false, &row);
 	if (ret) {
@@ -613,18 +608,30 @@ KsPlot::Graph *KsGLWidget::_newTaskGraph(int pid)
 	return graph;
 }
 
-bool KsGLWidget::_find(QMouseEvent *event, int variance, bool joined,
-		       size_t *row)
+/**
+ * @brief Find the KernelShark entry under the the cursor.
+ *
+ * @param point: The position of the cursor.
+ * @param variance: The variance of the position (range) in which an entry will
+ *		    be searched.
+ * @param joined: It True, search also in the associated CPU/Task graph.
+ * @param index: Output location for the index of the entry under the cursor.
+ * 		 If no entry has been found, the outputted value is zero.
+ *
+ * @returns True, if an entry has been found, otherwise False.
+ */
+bool KsGLWidget::find(const QPoint &point, int variance, bool joined,
+		      size_t *index)
 {
 	/*
 	 * Get the bin, pid and cpu numbers.
 	 * Remember that one bin corresponds to one pixel.
 	 */
-	int bin = event->pos().x() - _hMargin;
-	int cpu = _getCPU(event->pos().y());
-	int pid = _getPid(event->pos().y());
+	int bin = point.x() - _hMargin;
+	int cpu = getPlotCPU(point);
+	int pid = getPlotPid(point);
 
-	return _find(bin, cpu, pid, variance, joined, row);
+	return _find(bin, cpu, pid, variance, joined, index);
 }
 
 int KsGLWidget::_getNextCPU(int pid, int bin)
@@ -766,9 +773,8 @@ bool KsGLWidget::_find(int bin, int cpu, int pid,
 bool KsGLWidget::_findAndSelect(QMouseEvent *event)
 {
 	size_t row;
-	bool found = _find(event, 10, true, &row);
+	bool found = find(event->pos(), 10, true, &row);
 
-	emit deselect();
 	if (found) {
 		emit select(row);
 		emit updateView(row, true);
@@ -892,9 +898,10 @@ int KsGLWidget::_posInRange(int x)
 	return posX;
 }
 
-int KsGLWidget::_getCPU(int y)
+/** Get the CPU Id of the Graph plotted at given position. */
+int KsGLWidget::getPlotCPU(const QPoint &point)
 {
-	int cpuId;
+	int cpuId, y = point.y();
 
 	if (_cpuList.count() == 0)
 		return -1;
@@ -906,9 +913,10 @@ int KsGLWidget::_getCPU(int y)
 	return _cpuList[cpuId];
 }
 
-int KsGLWidget::_getPid(int y)
+/** Get the CPU Id of the Graph plotted at given position. */
+int KsGLWidget::getPlotPid(const QPoint &point)
 {
-	int pidId;
+	int pidId, y = point.y();
 
 	if (_taskList.count() == 0)
 		return -1;
diff --git a/kernel-shark-qt/src/KsGLWidget.hpp b/kernel-shark-qt/src/KsGLWidget.hpp
index 662cd26..6fbf534 100644
--- a/kernel-shark-qt/src/KsGLWidget.hpp
+++ b/kernel-shark-qt/src/KsGLWidget.hpp
@@ -98,6 +98,13 @@ public:
 			  int *graphCPU,
 			  int *graphTask);
 
+	bool find(const QPoint &point, int variance, bool joined,
+		  size_t *index);
+
+	int getPlotCPU(const QPoint &point);
+
+	int getPlotPid(const QPoint &point);
+
 	/** CPUs to be plotted. */
 	QVector<int>	_cpuList;
 
@@ -141,13 +148,6 @@ signals:
 	 */
 	void select(size_t pos);
 
-	/**
-	 * This signal is emitted in the case of a right mouse button click or
-	 * in the case of a double click over an empty area (no visible
-	 * KernelShark entries).
-	 */
-	void deselect();
-
 	/**
 	 * This signal is emitted when the KsTraceViewer widget needs to be
 	 * updated.
@@ -195,10 +195,6 @@ private:
 
 	int _posInRange(int x);
 
-	int _getCPU(int y);
-
-	int _getPid(int y);
-
 	void _rangeBoundInit(int x);
 
 	void _rangeBoundStretched(int x);
@@ -207,8 +203,6 @@ private:
 
 	bool _findAndSelect(QMouseEvent *event);
 
-	bool _find(QMouseEvent *event, int variance, bool joined, size_t *row);
-
 	bool _find(int bin, int cpu, int pid,
 		   int variance, bool joined, size_t *row);
 
@@ -217,6 +211,8 @@ private:
 	int _getLastTask(struct kshark_trace_histo *histo, int bin, int cpu);
 
 	int _getLastCPU(struct kshark_trace_histo *histo, int bin, int pid);
+
+	void _deselect();
 };
 
 #endif
diff --git a/kernel-shark-qt/src/KsMainWindow.cpp b/kernel-shark-qt/src/KsMainWindow.cpp
index 8e8484f..5c9a0fa 100644
--- a/kernel-shark-qt/src/KsMainWindow.cpp
+++ b/kernel-shark-qt/src/KsMainWindow.cpp
@@ -93,14 +93,17 @@ KsMainWindow::KsMainWindow(QWidget *parent)
 	connect(&_view,		&KsTraceViewer::select,
 		&_graph,	&KsTraceGraph::markEntry);
 
-	connect(&_view,		&KsTraceViewer::plotTask,
+	connect(&_view,		&KsTraceViewer::addTaskPlot,
 		&_graph,	&KsTraceGraph::addTaskPlot);
 
 	connect(_graph.glPtr(), &KsGLWidget::updateView,
 		&_view,		&KsTraceViewer::showRow);
 
-	connect(_graph.glPtr(), &KsGLWidget::deselect,
-		&_view,		&KsTraceViewer::deselect);
+	connect(&_graph,	&KsTraceGraph::deselect,
+		this,		&KsMainWindow::_deselect);
+
+	connect(&_view,		&KsTraceViewer::deselect,
+		this,		&KsMainWindow::_deselect);
 
 	connect(&_data,		&KsDataStore::updateWidgets,
 		&_view,		&KsTraceViewer::update);
@@ -1040,3 +1043,11 @@ void KsMainWindow::_splitterMoved(int pos, int index)
 {
 	_session.saveSplitterSize(_splitter);
 }
+
+void KsMainWindow::_deselect()
+{
+	_view.clearSelection();
+	_mState.activeMarker().remove();
+	_mState.updateLabels();
+	_graph.glPtr()->model()->update();
+}
diff --git a/kernel-shark-qt/src/KsMainWindow.hpp b/kernel-shark-qt/src/KsMainWindow.hpp
index d711ec1..b9b681f 100644
--- a/kernel-shark-qt/src/KsMainWindow.hpp
+++ b/kernel-shark-qt/src/KsMainWindow.hpp
@@ -210,6 +210,8 @@ private:
 	void _error(const QString &text, const QString &errCode,
 		    bool resize, bool unloadPlugins);
 
+	void _deselect();
+
 private slots:
 	void _captureFinished(int, QProcess::ExitStatus);
 };
diff --git a/kernel-shark-qt/src/KsQuickContextMenu.cpp b/kernel-shark-qt/src/KsQuickContextMenu.cpp
new file mode 100644
index 0000000..0a8e527
--- /dev/null
+++ b/kernel-shark-qt/src/KsQuickContextMenu.cpp
@@ -0,0 +1,274 @@
+// SPDX-License-Identifier: LGPL-2.1
+
+/*
+ * Copyright (C) 2018 VMware Inc, Yordan Karadzhov <ykaradzhov@vmware.com>
+ */
+
+/**
+ *  @file    KsQuickContextMenu.cpp
+ *  @brief   Quick Context Menus for KernelShark.
+ */
+
+#include "KsQuickContextMenu.hpp"
+#include "KsTraceGraph.hpp"
+
+/**
+ * @brief Create KsQuickMarkerMenu.
+ *
+ * @param dm: The State machine of the Dual marker.
+ * @param parent: The parent of this widget.
+ */
+KsQuickMarkerMenu::KsQuickMarkerMenu(KsDualMarkerSM *dm, QWidget *parent)
+: QMenu("Context Menu", parent),
+  _dm(dm),
+  _deselectAction(this)
+{
+	if (dm->activeMarker()._isSet) {
+		addSection("Marker menu");
+		_deselectAction.setText("Deselect");
+
+		connect(&_deselectAction,	&QAction::triggered,
+			this,			&KsQuickMarkerMenu::deselect);
+
+		addAction(&_deselectAction);
+	}
+}
+
+/**
+ * @brief Create KsQuickContextMenu.
+ *
+ * @param data: Input location for the KsDataStore object.
+ * @param row: The index of the entry used to initialize the menu.
+ * @param dm: The State machine of the Dual marker.
+ * @param parent: The parent of this widget.
+ */
+KsQuickContextMenu::KsQuickContextMenu(KsDataStore *data, size_t row,
+				       KsDualMarkerSM *dm,
+				       QWidget *parent)
+: KsQuickMarkerMenu(dm, parent),
+  _data(data),
+  _row(row),
+  _hideTaskAction(this),
+  _showTaskAction(this),
+  _hideEventAction(this),
+  _showEventAction(this),
+  _addCPUPlotAction(this),
+  _addTaskPlotAction(this),
+  _removeCPUPlotAction(this),
+  _removeTaskPlotAction(this),
+  _deselectAction(this)
+{
+	typedef void (KsQuickContextMenu::*mfp)();
+	QString taskName, parentName, descr;
+	KsTraceGraph *graphs;
+	int pid, cpu;
+
+	if (!parent || !_data)
+		return;
+
+	taskName = kshark_get_task_easy(_data->rows()[_row]);
+	pid = kshark_get_pid_easy(_data->rows()[_row]);
+	cpu = _data->rows()[_row]->cpu;
+
+	auto lamAddAction = [this, &descr] (QAction *action, mfp mf) {
+		action->setText(descr);
+
+		connect(action,	&QAction::triggered,
+			this,	mf);
+
+		addAction(action);
+	};
+
+	parentName = parent->metaObject()->className();
+
+	addSection("Pointer menu");
+	descr = "Hide task [";
+	descr += taskName;
+	descr += "-";
+	descr += QString("%1").arg(pid);
+	descr += "]";
+	lamAddAction(&_hideTaskAction, &KsQuickContextMenu::_hideTask);
+
+	descr = "Show task [";
+	descr += taskName;
+	descr += "-";
+	descr += QString("%1").arg(pid);
+	descr += "] only";
+	lamAddAction(&_showTaskAction, &KsQuickContextMenu::_showTask);
+
+	descr = "Hide event [";
+	descr += kshark_get_event_name_easy(_data->rows()[_row]);
+	descr += "]";
+	lamAddAction(&_hideEventAction, &KsQuickContextMenu::_hideEvent);
+
+	descr = "Show event [";
+	descr += kshark_get_event_name_easy(_data->rows()[_row]);
+	descr += "] only";
+	lamAddAction(&_showEventAction, &KsQuickContextMenu::_showEvent);
+
+	if (parentName == "KsTraceViewer") {
+		descr = "Add [";
+		descr += taskName;
+		descr += "-";
+		descr += QString("%1").arg(pid);
+		descr += "] plot";
+		lamAddAction(&_addTaskPlotAction,
+			     &KsQuickContextMenu::_addTaskPlot);
+	}
+
+	if (parentName == "KsTraceGraph" &&
+	    (graphs = dynamic_cast<KsTraceGraph *>(parent))) {
+		if (graphs->glPtr()->_taskList.contains(pid)) {
+			descr = "Remove [";
+			descr += taskName;
+			descr += "-";
+			descr += QString("%1").arg(_data->rows()[_row]->pid);
+			descr += "] plot";
+			lamAddAction(&_removeTaskPlotAction,
+				     &KsQuickContextMenu::_removeTaskPlot);
+		} else {
+			descr = "Add [";
+			descr += taskName;
+			descr += "-";
+			descr += QString("%1").arg(_data->rows()[_row]->pid);
+			descr += "] plot";
+			lamAddAction(&_addTaskPlotAction,
+				     &KsQuickContextMenu::_addTaskPlot);
+		}
+
+		if (graphs->glPtr()->_cpuList.contains(cpu)) {
+			descr = "Remove [CPU ";
+			descr += QString("%1").arg(cpu);
+			descr += "] plot";
+			lamAddAction(&_removeCPUPlotAction,
+				     &KsQuickContextMenu::_removeCPUPlot);
+		} else {
+			descr = "Add [CPU ";
+			descr += QString("%1").arg(cpu);
+			descr += "] plot";
+			lamAddAction(&_addCPUPlotAction,
+				     &KsQuickContextMenu::_addCPUPlot);
+		}
+	}
+}
+
+void KsQuickContextMenu::_hideTask()
+{
+	int pid = kshark_get_pid_easy(_data->rows()[_row]);
+	kshark_context *kshark_ctx(nullptr);
+	QVector<int> vec;
+
+	if (!kshark_instance(&kshark_ctx))
+		return;
+
+	vec =_getFilterVector(kshark_ctx->hide_task_filter, pid);
+	_data->applyPosTaskFilter(vec);
+}
+
+void KsQuickContextMenu::_showTask()
+{
+	int pid = kshark_get_pid_easy(_data->rows()[_row]);
+
+	_data->applyPosTaskFilter(QVector<int>(1, pid));
+}
+
+void KsQuickContextMenu::_hideEvent()
+{
+	int eventId = kshark_get_event_id_easy(_data->rows()[_row]);
+	kshark_context *kshark_ctx(nullptr);
+	QVector<int> vec;
+
+	if (!kshark_instance(&kshark_ctx))
+		return;
+
+	vec =_getFilterVector(kshark_ctx->hide_event_filter, eventId);
+	_data->applyNegEventFilter(vec);
+}
+
+void KsQuickContextMenu::_showEvent()
+{
+	int eventId = kshark_get_event_id_easy(_data->rows()[_row]);
+
+	_data->applyPosEventFilter(QVector<int>(1, eventId));
+}
+
+void KsQuickContextMenu::_addTaskPlot()
+{
+	int pid = kshark_get_pid_easy(_data->rows()[_row]);
+
+	emit addTaskPlot(pid);
+}
+
+void KsQuickContextMenu::_addCPUPlot()
+{
+	emit addCPUPlot(_data->rows()[_row]->cpu);
+}
+
+void KsQuickContextMenu::_removeTaskPlot()
+{
+	int pid = kshark_get_pid_easy(_data->rows()[_row]);
+
+	emit removeTaskPlot(pid);
+}
+
+void KsQuickContextMenu::_removeCPUPlot()
+{
+	emit removeCPUPlot(_data->rows()[_row]->cpu);
+}
+
+/**
+ * @brief Create KsRmPlotContextMenu.
+ *
+ * @param dm: The State machine of the Dual marker.
+ * @param parent: The parent of this widget.
+ */
+KsRmPlotContextMenu::KsRmPlotContextMenu(KsDualMarkerSM *dm,
+					 QWidget *parent)
+: KsQuickMarkerMenu(dm, parent),
+  _removePlotAction(this)
+{
+	addSection("Plots");
+
+	connect(&_removePlotAction,	&QAction::triggered,
+		this,			&KsRmPlotContextMenu::removePlot);
+
+	addAction(&_removePlotAction);
+}
+
+/**
+ * @brief Create KsRmCPUPlotMenu.
+ *
+ * @param dm: The State machine of the Dual marker.
+ * @param cpu : CPU Id.
+ * @param parent: The parent of this widget.
+ */
+KsRmCPUPlotMenu::KsRmCPUPlotMenu(KsDualMarkerSM *dm, int cpu,
+				 QWidget *parent)
+: KsRmPlotContextMenu(dm, parent)
+{
+	_removePlotAction.setText(QString("Remove [CPU %1]").arg(cpu));
+}
+
+/**
+ * @brief Create KsRmTaskPlotMenu.
+ *
+ * @param dm: The State machine of the Dual marker.
+ * @param pid: Process Id.
+ * @param parent: The parent of this widget.
+ */
+KsRmTaskPlotMenu::KsRmTaskPlotMenu(KsDualMarkerSM *dm, int pid,
+				   QWidget *parent)
+: KsRmPlotContextMenu(dm, parent)
+{
+	kshark_context *kshark_ctx(nullptr);
+	QString descr("Remove [ ");
+
+	if (!kshark_instance(&kshark_ctx))
+		return;
+
+	descr += tep_data_comm_from_pid(kshark_ctx->pevent, pid);
+	descr += "-";
+	descr += QString("%1").arg(pid);
+	descr += "] plot";
+	_removePlotAction.setText(descr);
+}
diff --git a/kernel-shark-qt/src/KsQuickContextMenu.hpp b/kernel-shark-qt/src/KsQuickContextMenu.hpp
new file mode 100644
index 0000000..040942f
--- /dev/null
+++ b/kernel-shark-qt/src/KsQuickContextMenu.hpp
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: LGPL-2.1 */
+
+/*
+ * Copyright (C) 2018 VMware Inc, Yordan Karadzhov <ykaradzhov@vmware.com>
+ */
+
+/**
+ *  @file    KsQuickContextMenu.hpp
+ *  @brief   Quick Context Menus for KernelShark.
+ */
+
+#ifndef _KS_QUICK_CTX_MENU_H
+#define _KS_QUICK_CTX_MENU_H
+
+#include "KsDualMarker.hpp"
+#include "KsUtils.hpp"
+#include "KsGLWidget.hpp"
+
+/**
+ * The KsQuickMarkerMenu class provides menu for quick Dual Marker related
+ * actions.
+ */
+class KsQuickMarkerMenu : public QMenu {
+	Q_OBJECT
+public:
+	KsQuickMarkerMenu(KsDualMarkerSM *dm, QWidget *parent = nullptr);
+
+signals:
+	/** Signal to deselect the active marker. */
+	void deselect();
+
+private:
+	KsDualMarkerSM	*_dm;
+
+	QAction _deselectAction;
+};
+
+/**
+ * The KsQuickFilterMenu class provides a menu for easy filtering and plotting.
+ * The menu is initialized from a single kshark_entry and uses the content of
+ * this entry to provides quick actions for filtering and plottin.
+ */
+class KsQuickContextMenu : public KsQuickMarkerMenu {
+	Q_OBJECT
+public:
+	KsQuickContextMenu() = delete;
+
+	KsQuickContextMenu(KsDataStore *data, size_t row,
+			   KsDualMarkerSM *dm,
+			   QWidget *parent = nullptr);
+
+signals:
+	/** Signal to add a task plot. */
+	void addTaskPlot(int);
+
+	/** Signal to add a CPU plot. */
+	void addCPUPlot(int);
+
+	/** Signal to remove a task plot. */
+	void removeTaskPlot(int);
+
+	/** Signal to remove a CPU plot. */
+	void removeCPUPlot(int);
+
+private:
+	void _hideTask();
+
+	void _showTask();
+
+	void _hideEvent();
+
+	void _showEvent();
+
+	void _addCPUPlot();
+
+	void _addTaskPlot();
+
+	void _removeCPUPlot();
+
+	void _removeTaskPlot();
+
+	KsDataStore	*_data;
+
+	size_t		_row;
+
+	QAction _hideTaskAction, _showTaskAction;
+
+	QAction _hideEventAction, _showEventAction;
+
+	QAction _addCPUPlotAction;
+
+	QAction _addTaskPlotAction;
+
+	QAction _removeCPUPlotAction;
+
+	QAction _removeTaskPlotAction;
+
+	QAction _deselectAction;
+};
+
+/**
+ * The KsQuickMarkerMenu is a baser class for Remove Plot menus.
+ */
+class KsRmPlotContextMenu : public KsQuickMarkerMenu {
+	Q_OBJECT
+public:
+	KsRmPlotContextMenu() = delete;
+
+	KsRmPlotContextMenu(KsDualMarkerSM *dm, QWidget *parent = nullptr);
+
+signals:
+	/** Signal to remove a plot. */
+	void removePlot(int);
+
+protected:
+	/** Menu action. */
+	QAction _removePlotAction;
+};
+
+/**
+ * The KsQuickMarkerMenu class provides CPU Plot remove menus.
+ */
+struct KsRmCPUPlotMenu : public KsRmPlotContextMenu {
+	KsRmCPUPlotMenu(KsDualMarkerSM *dm, int cpu,
+			QWidget *parent = nullptr);
+};
+
+/**
+ * The KsQuickMarkerMenu class provides Task Plot remove menus.
+ */
+struct KsRmTaskPlotMenu : public KsRmPlotContextMenu {
+	KsRmTaskPlotMenu(KsDualMarkerSM *dm, int pid,
+			 QWidget *parent = nullptr);
+};
+
+#endif
diff --git a/kernel-shark-qt/src/KsTraceGraph.cpp b/kernel-shark-qt/src/KsTraceGraph.cpp
index 29a5950..09b322a 100644
--- a/kernel-shark-qt/src/KsTraceGraph.cpp
+++ b/kernel-shark-qt/src/KsTraceGraph.cpp
@@ -13,6 +13,7 @@
 #include "KsUtils.hpp"
 #include "KsDualMarker.hpp"
 #include "KsTraceGraph.hpp"
+#include "KsQuickContextMenu.hpp"
 
 /** Create a default (empty) Trace graph widget. */
 KsTraceGraph::KsTraceGraph(QWidget *parent)
@@ -134,6 +135,10 @@ KsTraceGraph::KsTraceGraph(QWidget *parent)
 	connect(_glWindow.model(),	&KsGraphModel::modelReset,
 		this,			&KsTraceGraph::_updateTimeLegends);
 
+	_glWindow.setContextMenuPolicy(Qt::CustomContextMenu);
+	connect(&_glWindow,	&QTableView::customContextMenuRequested,
+		this,		&KsTraceGraph::_onCustomContextMenu);
+
 	_scrollArea.setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
 	_scrollArea.setWidget(&_drawWindow);
 
@@ -447,6 +452,26 @@ void KsTraceGraph::addTaskPlot(int pid)
 	_selfUpdate();
 }
 
+/** Remove a CPU graph from the existing list of CPU graphs. */
+void KsTraceGraph::removeCPUPlot(int cpu)
+{
+	if (!_glWindow._cpuList.contains(cpu))
+		return;
+
+	_glWindow._cpuList.removeAll(cpu);
+	_selfUpdate();
+}
+
+/** Remove a Task graph from the existing list of Task graphs. */
+void KsTraceGraph::removeTaskPlot(int pid)
+{
+	if (!_glWindow._taskList.contains(pid))
+		return;
+
+	_glWindow._taskList.removeAll(pid);
+	_selfUpdate();
+}
+
 /** Update the content of all graphs. */
 void KsTraceGraph::update(KsDataStore *data)
 {
@@ -689,3 +714,72 @@ void KsTraceGraph::_updateGraphs(GraphActions action)
 		QCoreApplication::processEvents();
 	}
 }
+
+void KsTraceGraph::_onCustomContextMenu(const QPoint &point)
+{
+	KsQuickMarkerMenu *menu(nullptr);
+	int cpu, pid;
+	size_t row;
+	bool found;
+
+	found = _glWindow.find(point, 20, true, &row);
+	if (found) {
+		/* KernelShark entry has been found under the cursor. */
+		KsQuickContextMenu *entryMenu;
+		menu = entryMenu = new KsQuickContextMenu(_data, row,
+							  _mState, this);
+
+		connect(entryMenu,	&KsQuickContextMenu::addTaskPlot,
+			this,		&KsTraceGraph::addTaskPlot);
+
+		connect(entryMenu,	&KsQuickContextMenu::addCPUPlot,
+			this,		&KsTraceGraph::addCPUPlot);
+
+		connect(entryMenu,	&KsQuickContextMenu::removeTaskPlot,
+			this,		&KsTraceGraph::removeTaskPlot);
+
+		connect(entryMenu,	&KsQuickContextMenu::removeCPUPlot,
+			this,		&KsTraceGraph::removeCPUPlot);
+	} else {
+		cpu = _glWindow.getPlotCPU(point);
+		if (cpu >= 0) {
+			/*
+			 * This is a CPU plot, but we do not have an entry
+			 * under the cursor.
+			 */
+			KsRmCPUPlotMenu *rmMenu;
+			menu = rmMenu = new KsRmCPUPlotMenu(_mState, cpu, this);
+
+			auto lamRmPlot = [&cpu, this] () {
+				removeCPUPlot(cpu);
+			};
+
+			connect(rmMenu, &KsRmPlotContextMenu::removePlot,
+				lamRmPlot);
+		}
+
+		pid = _glWindow.getPlotPid(point);
+		if (pid >= 0) {
+			/*
+			 * This is a Task plot, but we do not have an entry
+			 * under the cursor.
+			 */
+			KsRmTaskPlotMenu *rmMenu;
+			menu = rmMenu = new KsRmTaskPlotMenu(_mState, pid, this);
+
+			auto lamRmPlot = [&pid, this] () {
+				removeTaskPlot(pid);
+			};
+
+			connect(rmMenu, &KsRmPlotContextMenu::removePlot,
+				lamRmPlot);
+		}
+	}
+
+	if (menu) {
+		connect(menu,	&KsQuickMarkerMenu::deselect,
+			this,	&KsTraceGraph::deselect);
+
+		menu->exec(mapToGlobal(point));
+	}
+}
diff --git a/kernel-shark-qt/src/KsTraceGraph.hpp b/kernel-shark-qt/src/KsTraceGraph.hpp
index 395cc1b..c53258c 100644
--- a/kernel-shark-qt/src/KsTraceGraph.hpp
+++ b/kernel-shark-qt/src/KsTraceGraph.hpp
@@ -60,6 +60,10 @@ public:
 
 	void addTaskPlot(int);
 
+	void removeCPUPlot(int);
+
+	void removeTaskPlot(int);
+
 	void update(KsDataStore *data);
 
 	void updateGeom();
@@ -68,6 +72,14 @@ public:
 
 	bool eventFilter(QObject* obj, QEvent* evt) override;
 
+signals:
+	/**
+	 * This signal is emitted in the case of a right mouse button click or
+	 * in the case of a double click over an empty area (no visible
+	 * KernelShark entries).
+	 */
+	void deselect();
+
 private:
 
 	void _zoomIn();
@@ -105,6 +117,8 @@ private:
 
 	void _updateGraphs(GraphActions action);
 
+	void _onCustomContextMenu(const QPoint &point);
+
 	QToolBar	_pointerBar, _navigationBar;
 
 	QPushButton	_zoomInButton, _quickZoomInButton;
diff --git a/kernel-shark-qt/src/KsTraceViewer.cpp b/kernel-shark-qt/src/KsTraceViewer.cpp
index 64c9fb7..d52d7e3 100644
--- a/kernel-shark-qt/src/KsTraceViewer.cpp
+++ b/kernel-shark-qt/src/KsTraceViewer.cpp
@@ -14,9 +14,22 @@
 #include <future>
 
 // KernelShark
+#include "KsQuickContextMenu.hpp"
 #include "KsTraceViewer.hpp"
 #include "KsWidgetsLib.hpp"
 
+/**
+ * Reimplemented handler for mouse press events. Right mouse click events will
+ * be ignored. This is done because we want the Right click is being used to
+ * open a Context menu.
+ */
+void KsTableView::mousePressEvent(QMouseEvent *e) {
+	if(e->button() == Qt::RightButton)
+		return;
+
+	QTableView::mousePressEvent(e);
+}
+
 /** Create a default (empty) Trace viewer widget. */
 KsTraceViewer::KsTraceViewer(QWidget *parent)
 : QWidget(parent),
@@ -248,10 +261,13 @@ void KsTraceViewer::_onCustomContextMenu(const QPoint &point)
 		 * of the row number in the source model.
 		 */
 		size_t row = _proxyModel.mapRowFromSource(i.row());
-		KsQuickEntryMenu menu(_data, row, this);
+		KsQuickContextMenu menu(_data, row, _mState, this);
 
-		connect(&menu,	&KsQuickEntryMenu::plotTask,
-			this,	&KsTraceViewer::plotTask);
+		connect(&menu,	&KsQuickContextMenu::addTaskPlot,
+			this,	&KsTraceViewer::addTaskPlot);
+
+		connect(&menu,	&KsQuickMarkerMenu::deselect,
+			this,	&KsTraceViewer::deselect);
 
 		menu.exec(mapToGlobal(point));
 	}
@@ -424,8 +440,10 @@ void KsTraceViewer::_clicked(const QModelIndex& i)
 	 */
 	size_t row = _proxyModel.mapRowFromSource(i.row());
 
-	_setSearchIterator(row);
-	_updateSearchCount();
+	if (_searchDone && _matchList.count()) {
+		_setSearchIterator(row);
+		_updateSearchCount();
+	}
 
 	if (_graphFollows)
 		emit select(row); // Send a signal to the Graph widget.
@@ -460,7 +478,7 @@ void KsTraceViewer::showRow(size_t r, bool mark)
 }
 
 /** Deselects the selected items (row) if any. */
-void KsTraceViewer::deselect()
+void KsTraceViewer::clearSelection()
 {
 	_view.clearSelection();
 }
diff --git a/kernel-shark-qt/src/KsTraceViewer.hpp b/kernel-shark-qt/src/KsTraceViewer.hpp
index 50c9115..4e35c17 100644
--- a/kernel-shark-qt/src/KsTraceViewer.hpp
+++ b/kernel-shark-qt/src/KsTraceViewer.hpp
@@ -20,6 +20,21 @@
 #include "KsModels.hpp"
 #include "KsDualMarker.hpp"
 
+/**
+ * Table View class, needed in order to reimplemented the handler for mouse
+ * press events.
+ */
+class KsTableView : public QTableView
+{
+	Q_OBJECT
+public:
+	/** Create KsTableView. */
+	explicit KsTableView(QWidget *parent = nullptr)
+	: QTableView(parent) {};
+
+	void mousePressEvent(QMouseEvent *event) override;
+};
+
 /**
  * The KsTraceViewer class provides a widget for browsing in the trace data
  * shown in a text form.
@@ -48,7 +63,7 @@ public:
 
 	void showRow(size_t r, bool mark);
 
-	void deselect();
+	void clearSelection();
 
 	void update(KsDataStore *data);
 
@@ -57,15 +72,21 @@ signals:
 	void select(size_t);
 
 	/**
-	 * This signal is used to re-emitted the plotTask signal of the
-	 * KsQuickEntryMenu.
+	 * This signal is used to re-emitted the addTaskPlot signal of the
+	 * KsQuickContextMenu.
 	 */
-	void plotTask(int pid);
+	void addTaskPlot(int pid);
+
+	/**
+	 * This signal is used to re-emitted the deselect signal of the
+	 * KsQuickMarkerMenu.
+	 */
+	void deselect();
 
 private:
 	QVBoxLayout	_layout;
 
-	QTableView	_view;
+	KsTableView	_view;
 
 	KsViewModel		_model;
 
@@ -145,7 +166,6 @@ private:
 	int _getSelectedDataRow();
 
 private slots:
-
 	void _searchEdit(int);
 };
 
diff --git a/kernel-shark-qt/src/KsWidgetsLib.cpp b/kernel-shark-qt/src/KsWidgetsLib.cpp
index 191ea7d..4b41f86 100644
--- a/kernel-shark-qt/src/KsWidgetsLib.cpp
+++ b/kernel-shark-qt/src/KsWidgetsLib.cpp
@@ -798,123 +798,3 @@ KsPluginCheckBoxWidget::KsPluginCheckBoxWidget(QStringList pluginList,
 
 	_adjustSize();
 }
-
-/**
- * @brief Create KsQuickEntryMenu.
- *
- * @param data: Input location for the KsDataStore object.
- * @param row: The index of the entry used to initialize the menu.
- * @param parent: The parent of this widget.
- */
-KsQuickEntryMenu::KsQuickEntryMenu(KsDataStore *data, size_t row,
-				   QWidget *parent)
-: QMenu("Entry menu", parent),
-  _data(data),
-  _row(row),
-  _hideTaskAction(this),
-  _showTaskAction(this),
-  _hideEventAction(this),
-  _showEventAction(this),
-  _addTaskPlotAction(this)
-{
-	QString descr;
-
-	addSection("Quick Filter menu");
-
-	descr = "Hide task [";
-	descr += kshark_get_task_easy(_data->rows()[_row]);
-	descr += "-";
-	descr += QString("%1").arg(_data->rows()[_row]->pid);
-	descr += "]";
-
-	_hideTaskAction.setText(descr);
-
-	connect(&_hideTaskAction,	&QAction::triggered,
-		this,			&KsQuickEntryMenu::_hideTask);
-
-	addAction(&_hideTaskAction);
-
-	descr = "Show task [";
-	descr += kshark_get_task_easy(_data->rows()[_row]);
-	descr += "-";
-	descr += QString("%1").arg(_data->rows()[_row]->pid);
-	descr += "] only";
-
-	_showTaskAction.setText(descr);
-
-	connect(&_showTaskAction,	&QAction::triggered,
-		this,			&KsQuickEntryMenu::_showTask);
-
-	addAction(&_showTaskAction);
-
-	descr = "Hide event [";
-	descr += kshark_get_event_name_easy(_data->rows()[_row]);
-	descr += "]";
-
-	_hideEventAction.setText(descr);
-
-	connect(&_hideEventAction,	&QAction::triggered,
-		this,			&KsQuickEntryMenu::_hideEvent);
-
-	addAction(&_hideEventAction);
-
-	descr = "Show event [";
-	descr += kshark_get_event_name_easy(_data->rows()[_row]);
-	descr += "] only";
-
-	_showEventAction.setText(descr);
-
-	connect(&_showEventAction,	&QAction::triggered,
-		this,			&KsQuickEntryMenu::_showEvent);
-
-	addAction(&_showEventAction);
-
-	addSection("Quick Plot menu");
-	descr = "Add [";
-	descr += kshark_get_task_easy(_data->rows()[_row]);
-	descr += "-";
-	descr += QString("%1").arg(_data->rows()[_row]->pid);
-	descr += "] plot";
-
-	_addTaskPlotAction.setText(descr);
-
-	connect(&_addTaskPlotAction,	&QAction::triggered,
-		this,			&KsQuickEntryMenu::_addTaskPlot);
-
-	addAction(&_addTaskPlotAction);
-}
-
-void KsQuickEntryMenu::_hideTask()
-{
-	int pid = kshark_get_pid_easy(_data->rows()[_row]);
-
-	_data->applyNegTaskFilter(QVector<int>(1, pid));
-}
-
-void KsQuickEntryMenu::_showTask()
-{
-	int pid = kshark_get_pid_easy(_data->rows()[_row]);
-
-	_data->applyPosTaskFilter(QVector<int>(1, pid));
-}
-
-void KsQuickEntryMenu::_hideEvent()
-{
-	int eventId = kshark_get_event_id_easy(_data->rows()[_row]);
-
-	_data->applyNegEventFilter(QVector<int>(1, eventId));
-}
-
-void KsQuickEntryMenu::_showEvent()
-{
-	int eventId = kshark_get_event_id_easy(_data->rows()[_row]);
-
-	_data->applyPosEventFilter(QVector<int>(1, eventId));
-}
-
-void KsQuickEntryMenu::_addTaskPlot()
-{
-	int pid = kshark_get_pid_easy(_data->rows()[_row]);
-
-	emit plotTask(pid);
-}
diff --git a/kernel-shark-qt/src/KsWidgetsLib.hpp b/kernel-shark-qt/src/KsWidgetsLib.hpp
index c09bcd5..6f22374 100644
--- a/kernel-shark-qt/src/KsWidgetsLib.hpp
+++ b/kernel-shark-qt/src/KsWidgetsLib.hpp
@@ -347,48 +347,4 @@ struct KsPluginCheckBoxWidget : public KsCheckBoxTableWidget
 			       QWidget *parent = nullptr);
 };
 
-class KsDataStore;
-class KsGLWidget;
-
-/**
- * The KsQuickFilterMenu class provides a menu for easy filtering and plotting.
- * The menu is initialized from a single kshark_entry and uses the content of
- * this entry to provides quick actions for filtering and plottin.
- */
-class KsQuickEntryMenu : public QMenu
-{
-	Q_OBJECT
-public:
-	KsQuickEntryMenu() = delete;
-
-	explicit KsQuickEntryMenu(KsDataStore *data,
-				  size_t row,
-				  QWidget *parent = nullptr);
-
-signals:
-	/** Signal to add a task plot. */
-	void plotTask(int);
-
-private:
-	void _hideTask();
-
-	void _showTask();
-
-	void _hideEvent();
-
-	void _showEvent();
-
-	void _addTaskPlot();
-
-	KsDataStore	*_data;
-
-	size_t		 _row;
-
-	QAction _hideTaskAction, _showTaskAction;
-
-	QAction _hideEventAction, _showEventAction;
-
-	QAction _addTaskPlotAction;
-};
-
 #endif
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 10/17] kernel-shark-qt: Add keyboard shortcuts for deselecting the marker
  2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
                   ` (8 preceding siblings ...)
  2018-11-28 15:16 ` [PATCH 09/17] kernel-shark-qt: Add centralized context menu for View and Graph widgets Yordan Karadzhov
@ 2018-11-28 15:16 ` Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 11/17] kernel-shark-qt: Sort all graphs before plotting Yordan Karadzhov
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

The active marker can now be deselected by pressing "Ctrl + D".

Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
 kernel-shark-qt/src/KsMainWindow.cpp       | 7 ++++++-
 kernel-shark-qt/src/KsMainWindow.hpp       | 2 ++
 kernel-shark-qt/src/KsQuickContextMenu.cpp | 2 ++
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/kernel-shark-qt/src/KsMainWindow.cpp b/kernel-shark-qt/src/KsMainWindow.cpp
index 5c9a0fa..f4804bd 100644
--- a/kernel-shark-qt/src/KsMainWindow.cpp
+++ b/kernel-shark-qt/src/KsMainWindow.cpp
@@ -65,7 +65,8 @@ KsMainWindow::KsMainWindow(QWidget *parent)
   _colorPhaseSlider(Qt::Horizontal, this),
   _fullScreenModeAction("Full Screen Mode", this),
   _aboutAction("About", this),
-  _contentsAction("Contents", this)
+  _contentsAction("Contents", this),
+  _deselectShortcut(this)
 {
 	setWindowTitle("Kernel Shark");
 	_createActions();
@@ -114,6 +115,10 @@ KsMainWindow::KsMainWindow(QWidget *parent)
 	connect(&_plugins,	&KsPluginManager::dataReload,
 		&_data,		&KsDataStore::reload);
 
+	_deselectShortcut.setKey(Qt::CTRL + Qt::Key_D);
+	connect(&_deselectShortcut,	&QShortcut::activated,
+		this,			&KsMainWindow::_deselect);
+
 	_resizeEmpty();
 }
 
diff --git a/kernel-shark-qt/src/KsMainWindow.hpp b/kernel-shark-qt/src/KsMainWindow.hpp
index b9b681f..5938a25 100644
--- a/kernel-shark-qt/src/KsMainWindow.hpp
+++ b/kernel-shark-qt/src/KsMainWindow.hpp
@@ -147,6 +147,8 @@ private:
 
 	QAction		_contentsAction;
 
+	QShortcut        _deselectShortcut;
+
 	void _open();
 
 	void _restorSession();
diff --git a/kernel-shark-qt/src/KsQuickContextMenu.cpp b/kernel-shark-qt/src/KsQuickContextMenu.cpp
index 0a8e527..16b8d19 100644
--- a/kernel-shark-qt/src/KsQuickContextMenu.cpp
+++ b/kernel-shark-qt/src/KsQuickContextMenu.cpp
@@ -26,6 +26,8 @@ KsQuickMarkerMenu::KsQuickMarkerMenu(KsDualMarkerSM *dm, QWidget *parent)
 	if (dm->activeMarker()._isSet) {
 		addSection("Marker menu");
 		_deselectAction.setText("Deselect");
+		_deselectAction.setShortcut(tr("Ctrl+D"));
+		_deselectAction.setStatusTip(tr("Deselect marker"));
 
 		connect(&_deselectAction,	&QAction::triggered,
 			this,			&KsQuickMarkerMenu::deselect);
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 11/17] kernel-shark-qt: Sort all graphs before plotting
  2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
                   ` (9 preceding siblings ...)
  2018-11-28 15:16 ` [PATCH 10/17] kernel-shark-qt: Add keyboard shortcuts for deselecting the marker Yordan Karadzhov
@ 2018-11-28 15:16 ` Yordan Karadzhov
  2018-11-28 17:12   ` Steven Rostedt
  2018-11-28 15:16 ` [PATCH 12/17] kernel-shark-qt: Add CPU-based filtering to the C API Yordan Karadzhov
                   ` (5 subsequent siblings)
  16 siblings, 1 reply; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

The CPU/Task graphs are plotted in sorted order. The graph
having smallest CPU id/Pid will be plotted first (on top).

Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
 kernel-shark-qt/src/KsTraceGraph.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/kernel-shark-qt/src/KsTraceGraph.cpp b/kernel-shark-qt/src/KsTraceGraph.cpp
index 09b322a..0b5a8b1 100644
--- a/kernel-shark-qt/src/KsTraceGraph.cpp
+++ b/kernel-shark-qt/src/KsTraceGraph.cpp
@@ -439,6 +439,7 @@ void KsTraceGraph::addCPUPlot(int cpu)
 		return;
 
 	_glWindow._cpuList.append(cpu);
+	qSort(_glWindow._cpuList);
 	_selfUpdate();
 }
 
@@ -449,6 +450,7 @@ void KsTraceGraph::addTaskPlot(int pid)
 		return;
 
 	_glWindow._taskList.append(pid);
+	qSort(_glWindow._taskList);
 	_selfUpdate();
 }
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 12/17] kernel-shark-qt: Add CPU-based filtering to the C API
  2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
                   ` (10 preceding siblings ...)
  2018-11-28 15:16 ` [PATCH 11/17] kernel-shark-qt: Sort all graphs before plotting Yordan Karadzhov
@ 2018-11-28 15:16 ` Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 13/17] kernel-shark-qt: Add CPU-based filtering to KsDataStore Yordan Karadzhov
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

This patch adds "Show CPU" and "Hide CPU" filters to the C API of
KernelShark. The implementation of those filters follows the pattern
used to implement the Task (pid) and Event filters.

Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
 kernel-shark-qt/src/libkshark.c | 37 +++++++++++++++++++++++++++++++++
 kernel-shark-qt/src/libkshark.h | 17 +++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/kernel-shark-qt/src/libkshark.c b/kernel-shark-qt/src/libkshark.c
index b4b3d5b..86d3e58 100644
--- a/kernel-shark-qt/src/libkshark.c
+++ b/kernel-shark-qt/src/libkshark.c
@@ -41,6 +41,9 @@ static bool kshark_default_context(struct kshark_context **context)
 	kshark_ctx->show_event_filter = tracecmd_filter_id_hash_alloc();
 	kshark_ctx->hide_event_filter = tracecmd_filter_id_hash_alloc();
 
+	kshark_ctx->show_cpu_filter = tracecmd_filter_id_hash_alloc();
+	kshark_ctx->hide_cpu_filter = tracecmd_filter_id_hash_alloc();
+
 	kshark_ctx->filter_mask = 0x0;
 
 	/* Will free kshark_context_handler. */
@@ -180,6 +183,8 @@ void kshark_close(struct kshark_context *kshark_ctx)
 	tracecmd_filter_id_clear(kshark_ctx->hide_task_filter);
 	tracecmd_filter_id_clear(kshark_ctx->show_event_filter);
 	tracecmd_filter_id_clear(kshark_ctx->hide_event_filter);
+	tracecmd_filter_id_clear(kshark_ctx->show_cpu_filter);
+	tracecmd_filter_id_clear(kshark_ctx->hide_cpu_filter);
 
 	if (kshark_ctx->advanced_event_filter) {
 		tep_filter_reset(kshark_ctx->advanced_event_filter);
@@ -226,6 +231,9 @@ void kshark_free(struct kshark_context *kshark_ctx)
 	tracecmd_filter_id_hash_free(kshark_ctx->show_event_filter);
 	tracecmd_filter_id_hash_free(kshark_ctx->hide_event_filter);
 
+	tracecmd_filter_id_hash_free(kshark_ctx->show_cpu_filter);
+	tracecmd_filter_id_hash_free(kshark_ctx->hide_cpu_filter);
+
 	if (kshark_ctx->plugins) {
 		kshark_handle_plugins(kshark_ctx, KSHARK_PLUGIN_CLOSE);
 		kshark_free_plugin_list(kshark_ctx->plugins);
@@ -366,6 +374,12 @@ static bool kshark_show_event(struct kshark_context *kshark_ctx, int pid)
 	       filter_find(kshark_ctx->hide_event_filter, pid, false);
 }
 
+static bool kshark_show_cpu(struct kshark_context *kshark_ctx, int cpu)
+{
+	return filter_find(kshark_ctx->show_cpu_filter, cpu, true) &&
+	       filter_find(kshark_ctx->hide_cpu_filter, cpu, false);
+}
+
 /**
  * @brief Add an Id value to the filster specified by "filter_id".
  *
@@ -379,6 +393,12 @@ void kshark_filter_add_id(struct kshark_context *kshark_ctx,
 	struct tracecmd_filter_id *filter;
 
 	switch (filter_id) {
+		case KS_SHOW_CPU_FILTER:
+			filter = kshark_ctx->show_cpu_filter;
+			break;
+		case KS_HIDE_CPU_FILTER:
+			filter = kshark_ctx->hide_cpu_filter;
+			break;
 		case KS_SHOW_EVENT_FILTER:
 			filter = kshark_ctx->show_event_filter;
 			break;
@@ -409,6 +429,12 @@ void kshark_filter_clear(struct kshark_context *kshark_ctx, int filter_id)
 	struct tracecmd_filter_id *filter;
 
 	switch (filter_id) {
+		case KS_SHOW_CPU_FILTER:
+			filter = kshark_ctx->show_cpu_filter;
+			break;
+		case KS_HIDE_CPU_FILTER:
+			filter = kshark_ctx->hide_cpu_filter;
+			break;
 		case KS_SHOW_EVENT_FILTER:
 			filter = kshark_ctx->show_event_filter;
 			break;
@@ -444,6 +470,8 @@ bool kshark_filter_is_set(struct kshark_context *kshark_ctx)
 {
 	return filter_is_set(kshark_ctx->show_task_filter) ||
 	       filter_is_set(kshark_ctx->hide_task_filter) ||
+	       filter_is_set(kshark_ctx->show_cpu_filter) ||
+	       filter_is_set(kshark_ctx->hide_cpu_filter) ||
 	       filter_is_set(kshark_ctx->show_event_filter) ||
 	       filter_is_set(kshark_ctx->hide_event_filter);
 }
@@ -505,6 +533,10 @@ void kshark_filter_entries(struct kshark_context *kshark_ctx,
 		if (!kshark_show_event(kshark_ctx, data[i]->event_id))
 			unset_event_filter_flag(kshark_ctx, data[i]);
 
+		/* Apply CPU filtering. */
+		if (!kshark_show_cpu(kshark_ctx, data[i]->cpu))
+			data[i]->visible &= ~kshark_ctx->filter_mask;
+
 		/* Apply task filtering. */
 		if (!kshark_show_task(kshark_ctx, data[i]->pid))
 			data[i]->visible &= ~kshark_ctx->filter_mask;
@@ -732,6 +764,11 @@ static size_t get_records(struct kshark_context *kshark_ctx,
 					unset_event_filter_flag(kshark_ctx, entry);
 				}
 
+				/* Apply CPU filtering. */
+				if (!kshark_show_cpu(kshark_ctx, entry->pid)) {
+					entry->visible &= ~kshark_ctx->filter_mask;
+				}
+
 				/* Apply task filtering. */
 				if (!kshark_show_task(kshark_ctx, entry->pid)) {
 					entry->visible &= ~kshark_ctx->filter_mask;
diff --git a/kernel-shark-qt/src/libkshark.h b/kernel-shark-qt/src/libkshark.h
index b94bdc3..eb8c261 100644
--- a/kernel-shark-qt/src/libkshark.h
+++ b/kernel-shark-qt/src/libkshark.h
@@ -110,6 +110,12 @@ struct kshark_context {
 	/** Hash of events to not display. */
 	struct tracecmd_filter_id	*hide_event_filter;
 
+	/** Hash of CPUs to filter on. */
+	struct tracecmd_filter_id	*show_cpu_filter;
+
+	/** Hash of CPUs to not display. */
+	struct tracecmd_filter_id	*hide_cpu_filter;
+
 	/**
 	 * Bit mask, controlling the visibility of the entries after filtering.
 	 * If given bit is set here, all entries which are filtered-out will
@@ -232,6 +238,17 @@ enum kshark_filter_type {
 	 * filtered-out.
 	 */
 	KS_HIDE_TASK_FILTER,
+
+	/**
+	 * Identifier of the filter, used to specified the CPUs to be shown.
+	 */
+	KS_SHOW_CPU_FILTER,
+
+	/**
+	 * Identifier of the filter, used to specified the CPUs to be
+	 * filtered-out.
+	 */
+	KS_HIDE_CPU_FILTER,
 };
 
 void kshark_filter_add_id(struct kshark_context *kshark_ctx,
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 13/17] kernel-shark-qt: Add CPU-based filtering to KsDataStore
  2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
                   ` (11 preceding siblings ...)
  2018-11-28 15:16 ` [PATCH 12/17] kernel-shark-qt: Add CPU-based filtering to the C API Yordan Karadzhov
@ 2018-11-28 15:16 ` Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 14/17] kernel-shark-qt: Add Hide CPU action to the Quick Context Menu Yordan Karadzhov
                   ` (3 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

This patch adds to the KsDataStore class methods for CPU filtering.

Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
 kernel-shark-qt/src/KsUtils.cpp | 21 +++++++++++++++++++--
 kernel-shark-qt/src/KsUtils.hpp |  4 ++++
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/kernel-shark-qt/src/KsUtils.cpp b/kernel-shark-qt/src/KsUtils.cpp
index c0e0f7d..2ebbae3 100644
--- a/kernel-shark-qt/src/KsUtils.cpp
+++ b/kernel-shark-qt/src/KsUtils.cpp
@@ -269,12 +269,17 @@ void KsDataStore::_applyIdFilter(int filterId, QVector<int> vec)
 			kshark_filter_clear(kshark_ctx, KS_SHOW_TASK_FILTER);
 			kshark_filter_clear(kshark_ctx, KS_HIDE_TASK_FILTER);
 			break;
+		case KS_SHOW_CPU_FILTER:
+		case KS_HIDE_CPU_FILTER:
+			kshark_filter_clear(kshark_ctx, KS_SHOW_CPU_FILTER);
+			kshark_filter_clear(kshark_ctx, KS_HIDE_CPU_FILTER);
+			break;
 		default:
 			return;
 	}
 
-	for (auto &&pid: vec)
-		kshark_filter_add_id(kshark_ctx, filterId, pid);
+	for (auto &&val: vec)
+		kshark_filter_add_id(kshark_ctx, filterId, val);
 
 	if (!_tep)
 		return;
@@ -319,6 +324,18 @@ void KsDataStore::applyNegEventFilter(QVector<int> vec)
 	_applyIdFilter(KS_HIDE_EVENT_FILTER, vec);
 }
 
+/** Apply Show CPU filter. */
+void KsDataStore::applyPosCPUFilter(QVector<int> vec)
+{
+	_applyIdFilter(KS_SHOW_CPU_FILTER, vec);
+}
+
+/** Apply Hide CPU filter. */
+void KsDataStore::applyNegCPUFilter(QVector<int> vec)
+{
+	_applyIdFilter(KS_HIDE_CPU_FILTER, vec);
+}
+
 /** Disable all filters. */
 void KsDataStore::clearAllFilters()
 {
diff --git a/kernel-shark-qt/src/KsUtils.hpp b/kernel-shark-qt/src/KsUtils.hpp
index 888ed56..052cc71 100644
--- a/kernel-shark-qt/src/KsUtils.hpp
+++ b/kernel-shark-qt/src/KsUtils.hpp
@@ -156,6 +156,10 @@ public:
 
 	void applyNegEventFilter(QVector<int>);
 
+	void applyPosCPUFilter(QVector<int>);
+
+	void applyNegCPUFilter(QVector<int>);
+
 	void clearAllFilters();
 
 signals:
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 14/17] kernel-shark-qt: Add Hide CPU action to the Quick Context Menu
  2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
                   ` (12 preceding siblings ...)
  2018-11-28 15:16 ` [PATCH 13/17] kernel-shark-qt: Add CPU-based filtering to KsDataStore Yordan Karadzhov
@ 2018-11-28 15:16 ` Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 15/17] kernel-shark-qt: Add the CPU filters to the Json config I/O Yordan Karadzhov
                   ` (2 subsequent siblings)
  16 siblings, 0 replies; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

Now the Quick Context Menu can be used to hide all data from a CPU core.
The CPU Id value is added to the list of CPUs to be filtered-out.

Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
 kernel-shark-qt/src/KsQuickContextMenu.cpp | 26 ++++++++++++++++++++++
 kernel-shark-qt/src/KsQuickContextMenu.hpp |  6 +++++
 2 files changed, 32 insertions(+)

diff --git a/kernel-shark-qt/src/KsQuickContextMenu.cpp b/kernel-shark-qt/src/KsQuickContextMenu.cpp
index 16b8d19..95ffc4f 100644
--- a/kernel-shark-qt/src/KsQuickContextMenu.cpp
+++ b/kernel-shark-qt/src/KsQuickContextMenu.cpp
@@ -54,6 +54,7 @@ KsQuickContextMenu::KsQuickContextMenu(KsDataStore *data, size_t row,
   _showTaskAction(this),
   _hideEventAction(this),
   _showEventAction(this),
+  _hideCPUAction(this),
   _addCPUPlotAction(this),
   _addTaskPlotAction(this),
   _removeCPUPlotAction(this),
@@ -108,6 +109,9 @@ KsQuickContextMenu::KsQuickContextMenu(KsDataStore *data, size_t row,
 	descr += "] only";
 	lamAddAction(&_showEventAction, &KsQuickContextMenu::_showEvent);
 
+	descr = QString("Hide CPU [%1]").arg(_data->rows()[_row]->cpu);
+	lamAddAction(&_hideCPUAction, &KsQuickContextMenu::_hideCPU);
+
 	if (parentName == "KsTraceViewer") {
 		descr = "Add [";
 		descr += taskName;
@@ -194,6 +198,28 @@ void KsQuickContextMenu::_showEvent()
 	_data->applyPosEventFilter(QVector<int>(1, eventId));
 }
 
+void KsQuickContextMenu::_hideCPU()
+{
+	kshark_context *kshark_ctx(nullptr);
+	QVector<int> vec;
+
+	if (!kshark_instance(&kshark_ctx))
+		return;
+
+	vec =_getFilterVector(kshark_ctx->hide_cpu_filter,
+			      _data->rows()[_row]->cpu);
+	_data->applyNegCPUFilter(vec);
+}
+
+QVector<int> KsQuickContextMenu::_getFilterVector(tracecmd_filter_id *filter, int newId)
+{
+	QVector<int> vec = KsUtils::getFilterIds(filter);
+	if (!vec.contains(newId))
+		vec.append(newId);
+
+	return vec;
+}
+
 void KsQuickContextMenu::_addTaskPlot()
 {
 	int pid = kshark_get_pid_easy(_data->rows()[_row]);
diff --git a/kernel-shark-qt/src/KsQuickContextMenu.hpp b/kernel-shark-qt/src/KsQuickContextMenu.hpp
index 040942f..6ca1b08 100644
--- a/kernel-shark-qt/src/KsQuickContextMenu.hpp
+++ b/kernel-shark-qt/src/KsQuickContextMenu.hpp
@@ -71,6 +71,8 @@ private:
 
 	void _showEvent();
 
+	void _hideCPU();
+
 	void _addCPUPlot();
 
 	void _addTaskPlot();
@@ -79,6 +81,8 @@ private:
 
 	void _removeTaskPlot();
 
+	QVector<int> _getFilterVector(tracecmd_filter_id *filter, int newId);
+
 	KsDataStore	*_data;
 
 	size_t		_row;
@@ -87,6 +91,8 @@ private:
 
 	QAction _hideEventAction, _showEventAction;
 
+	QAction _hideCPUAction;
+
 	QAction _addCPUPlotAction;
 
 	QAction _addTaskPlotAction;
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 15/17] kernel-shark-qt: Add the CPU filters to the Json config I/O
  2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
                   ` (13 preceding siblings ...)
  2018-11-28 15:16 ` [PATCH 14/17] kernel-shark-qt: Add Hide CPU action to the Quick Context Menu Yordan Karadzhov
@ 2018-11-28 15:16 ` Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 16/17] kernel-shark-qt: Add "Hide CPU" checkbox dialog to the Main window menu Yordan Karadzhov
  2018-11-28 15:16 ` [PATCH 17/17] kernel-shark-qt: Add the user filter mask to the Json config I/O Yordan Karadzhov
  16 siblings, 0 replies; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

This patch adds "Show CPU" and "Hide CPU" filters to the Json
config I/O, making possible to import/export those filters.
Saving/loading the CPU filters reuses some of the code used
so far by the Task filters. Because of this some functions
have been renamed.

Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
 kernel-shark-qt/src/libkshark-configio.c | 133 +++++++++++++++++------
 kernel-shark-qt/src/libkshark.h          |  28 ++++-
 2 files changed, 123 insertions(+), 38 deletions(-)

diff --git a/kernel-shark-qt/src/libkshark-configio.c b/kernel-shark-qt/src/libkshark-configio.c
index bf2a08b..a426e48 100644
--- a/kernel-shark-qt/src/libkshark-configio.c
+++ b/kernel-shark-qt/src/libkshark-configio.c
@@ -870,20 +870,20 @@ bool kshark_import_event_filter(struct tep_handle *pevent,
 	}
 }
 
-static bool kshark_task_filter_to_json(struct tracecmd_filter_id *filter,
-				       const char *filter_name,
-				       struct json_object *jobj)
+static bool kshark_filter_array_to_json(struct tracecmd_filter_id *filter,
+					const char *filter_name,
+					struct json_object *jobj)
 {
 	json_object *jfilter_data, *jpid = NULL;
 	int i, *ids;
 
 	/*
-	 * If this Json document already contains a description of the model,
+	 * If this Json document already contains a description of the filter,
 	 * delete this description.
 	 */
 	json_del_if_exist(jobj, filter_name);
 
-	/* Get the array of Ids to be fitered. */
+	/* Get the array of Ids to be filtered. */
 	ids = tracecmd_filter_ids(filter);
 	if (!ids)
 		return true;
@@ -918,7 +918,7 @@ static bool kshark_task_filter_to_json(struct tracecmd_filter_id *filter,
 }
 
 /**
- * @brief Record the current configuration of a Task Id filter into a
+ * @brief Record the current configuration of a simple Id filter into a
  *	  Configuration document.
  *
  * @param filter: Input location for an Id filter.
@@ -928,14 +928,14 @@ static bool kshark_task_filter_to_json(struct tracecmd_filter_id *filter,
  *
  * @returns True on success, otherwise False.
  */
-bool kshark_export_task_filter(struct tracecmd_filter_id *filter,
-			       const char *filter_name,
-			       struct kshark_config_doc *conf)
+bool kshark_export_filter_array(struct tracecmd_filter_id *filter,
+				const char *filter_name,
+				struct kshark_config_doc *conf)
 {
 	switch (conf->format) {
 	case KS_CONFIG_JSON:
-		return kshark_task_filter_to_json(filter, filter_name,
-						  conf->conf_doc);
+		return kshark_filter_array_to_json(filter, filter_name,
+						   conf->conf_doc);
 
 	default:
 		fprintf(stderr, "Document format %d not supported\n",
@@ -944,9 +944,9 @@ bool kshark_export_task_filter(struct tracecmd_filter_id *filter,
 	}
 }
 
-static bool kshark_task_filter_from_json(struct tracecmd_filter_id *filter,
-					 const char *filter_name,
-					 struct json_object *jobj)
+static bool kshark_filter_array_from_json(struct tracecmd_filter_id *filter,
+					  const char *filter_name,
+					  struct json_object *jobj)
 {
 	json_object *jfilter, *jpid;
 	int i, length;
@@ -981,7 +981,8 @@ static bool kshark_task_filter_from_json(struct tracecmd_filter_id *filter,
 }
 
 /**
- * @brief Load from Configuration document the configuration of a Task Id filter.
+ * @brief Load from Configuration document the configuration of a simple
+ *	  Id filter.
  *
  * @param filter: Input location for an Id filter.
  * @param filter_name: The name of the filter as showing up in the Config.
@@ -993,14 +994,14 @@ static bool kshark_task_filter_from_json(struct tracecmd_filter_id *filter,
  *	    document contains no data for this particular filter or in a case
  *	    of an error, the function returns False.
  */
-bool kshark_import_task_filter(struct tracecmd_filter_id *filter,
-			       const char *filter_name,
-			       struct kshark_config_doc *conf)
+bool kshark_import_filter_array(struct tracecmd_filter_id *filter,
+				const char *filter_name,
+				struct kshark_config_doc *conf)
 {
 	switch (conf->format) {
 	case KS_CONFIG_JSON:
-		return kshark_task_filter_from_json(filter, filter_name,
-						    conf->conf_doc);
+		return kshark_filter_array_from_json(filter, filter_name,
+						     conf->conf_doc);
 
 	default:
 		fprintf(stderr, "Document format %d not supported\n",
@@ -1269,14 +1270,52 @@ bool kshark_export_all_task_filters(struct kshark_context *kshark_ctx,
 
 	/* Save a filter only if it contains Id values. */
 	if (filter_is_set(kshark_ctx->show_task_filter))
-		ret &= kshark_export_task_filter(kshark_ctx->show_task_filter,
-						 KS_SHOW_TASK_FILTER_NAME,
-						 *conf);
+		ret &= kshark_export_filter_array(kshark_ctx->show_task_filter,
+						  KS_SHOW_TASK_FILTER_NAME,
+						  *conf);
 
 	if (filter_is_set(kshark_ctx->hide_task_filter))
-		ret &= kshark_export_task_filter(kshark_ctx->hide_task_filter,
-						 KS_HIDE_TASK_FILTER_NAME,
-						 *conf);
+		ret &= kshark_export_filter_array(kshark_ctx->hide_task_filter,
+						  KS_HIDE_TASK_FILTER_NAME,
+						  *conf);
+
+	return ret;
+}
+
+
+/**
+ * @brief Record the current configuration of "show cpu" and "hide cpu"
+ *	  filters into a Configuration document.
+ *
+ * @param kshark_ctx: Input location for session context pointer.
+ * @param conf: Input location for the kshark_config_doc instance. Currently
+ *		only Json format is supported. If NULL, a new Filter
+ *		Configuration document will be created.
+ *
+ * @returns True, if a filter has been recorded. If both filters contain
+ *	    no Id values or in a case of an error, the function returns False.
+ */
+bool kshark_export_all_cpu_filters(struct kshark_context *kshark_ctx,
+				   struct kshark_config_doc **conf)
+{
+	bool ret = true;
+
+	if (!*conf)
+		*conf = kshark_filter_config_new(KS_CONFIG_JSON);
+
+	if (!*conf)
+		return false;
+
+	/* Save a filter only if it contains Id values. */
+	if (filter_is_set(kshark_ctx->show_task_filter))
+		ret &= kshark_export_filter_array(kshark_ctx->show_cpu_filter,
+						  KS_SHOW_CPU_FILTER_NAME,
+						  *conf);
+
+	if (filter_is_set(kshark_ctx->hide_task_filter))
+		ret &= kshark_export_filter_array(kshark_ctx->hide_cpu_filter,
+						  KS_HIDE_CPU_FILTER_NAME,
+						  *conf);
 
 	return ret;
 }
@@ -1328,13 +1367,41 @@ bool kshark_import_all_task_filters(struct kshark_context *kshark_ctx,
 {
 	bool ret = false;
 
-	ret |= kshark_import_task_filter(kshark_ctx->hide_task_filter,
-					 KS_HIDE_TASK_FILTER_NAME,
-					 conf);
+	ret |= kshark_import_filter_array(kshark_ctx->hide_task_filter,
+					  KS_HIDE_TASK_FILTER_NAME,
+					  conf);
+
+	ret |= kshark_import_filter_array(kshark_ctx->show_task_filter,
+					  KS_SHOW_TASK_FILTER_NAME,
+					  conf);
+
+	return ret;
+}
+
+/**
+ * @brief Load from Configuration document the configuration of "show cpu"
+ *	  and "hide cpu" filters.
+ *
+ * @param kshark_ctx: Input location for session context pointer.
+ * @param conf: Input location for the kshark_config_doc instance. Currently
+ *		only Json format is supported.
+ *
+ * @returns True, if a filter has been loaded. If the filter configuration
+ *	    document contains no data for any cpu filter or in a case of an
+ *	    error, the function returns False.
+ */
+bool kshark_import_all_cpu_filters(struct kshark_context *kshark_ctx,
+				    struct kshark_config_doc *conf)
+{
+	bool ret = false;
+
+	ret |= kshark_import_filter_array(kshark_ctx->hide_cpu_filter,
+					  KS_HIDE_CPU_FILTER_NAME,
+					  conf);
 
-	ret |= kshark_import_task_filter(kshark_ctx->show_task_filter,
-					 KS_SHOW_TASK_FILTER_NAME,
-					 conf);
+	ret |= kshark_import_filter_array(kshark_ctx->show_cpu_filter,
+					  KS_SHOW_CPU_FILTER_NAME,
+					  conf);
 
 	return ret;
 }
@@ -1362,6 +1429,7 @@ kshark_export_all_filters(struct kshark_context *kshark_ctx,
 	if (!conf ||
 	    !kshark_export_all_event_filters(kshark_ctx, &conf) ||
 	    !kshark_export_all_task_filters(kshark_ctx, &conf) ||
+	    !kshark_export_all_cpu_filters(kshark_ctx, &conf) ||
 	    !kshark_export_adv_filters(kshark_ctx, &conf)) {
 		kshark_free_config_doc(conf);
 		return NULL;
@@ -1386,6 +1454,7 @@ bool kshark_import_all_filters(struct kshark_context *kshark_ctx,
 {
 	bool ret;
 	ret = kshark_import_all_task_filters(kshark_ctx, conf);
+	ret |= kshark_import_all_cpu_filters(kshark_ctx, conf);
 	ret |= kshark_import_all_event_filters(kshark_ctx, conf);
 	ret |= kshark_import_adv_filters(kshark_ctx, conf);
 
diff --git a/kernel-shark-qt/src/libkshark.h b/kernel-shark-qt/src/libkshark.h
index eb8c261..6a3eba6 100644
--- a/kernel-shark-qt/src/libkshark.h
+++ b/kernel-shark-qt/src/libkshark.h
@@ -488,6 +488,16 @@ enum kshark_config_formats {
  */
 #define KS_SHOW_TASK_FILTER_NAME	"show task filter"
 
+/**
+ * Field name for the Configuration document describing the Hide Task filter.
+ */
+#define KS_HIDE_CPU_FILTER_NAME		"hide cpu filter"
+
+/**
+ * Field name for the Configuration document describing the Show Task filter.
+ */
+#define KS_SHOW_CPU_FILTER_NAME		"show cpu filter"
+
 /**
  * Field name for the Configuration document describing the Advanced event
  * filter.
@@ -565,13 +575,13 @@ bool kshark_import_event_filter(struct tep_handle *pevent,
 				const char *filter_name,
 				struct kshark_config_doc *conf);
 
-bool kshark_export_task_filter(struct tracecmd_filter_id *filter,
-			       const char *filter_name,
-			       struct kshark_config_doc *conf);
+bool kshark_export_filter_array(struct tracecmd_filter_id *filter,
+				const char *filter_name,
+				struct kshark_config_doc *conf);
 
-bool kshark_import_task_filter(struct tracecmd_filter_id *filter,
-			       const char *filter_name,
-			       struct kshark_config_doc *conf);
+bool kshark_import_filter_array(struct tracecmd_filter_id *filter,
+				const char *filter_name,
+				struct kshark_config_doc *conf);
 
 bool kshark_export_all_event_filters(struct kshark_context *kshark_ctx,
 				     struct kshark_config_doc **conf);
@@ -579,6 +589,9 @@ bool kshark_export_all_event_filters(struct kshark_context *kshark_ctx,
 bool kshark_export_all_task_filters(struct kshark_context *kshark_ctx,
 				    struct kshark_config_doc **conf);
 
+bool kshark_export_all_cpu_filters(struct kshark_context *kshark_ctx,
+				   struct kshark_config_doc **conf);
+
 struct kshark_config_doc *
 kshark_export_all_filters(struct kshark_context *kshark_ctx,
 			  enum kshark_config_formats format);
@@ -589,6 +602,9 @@ bool kshark_import_all_event_filters(struct kshark_context *kshark_ctx,
 bool kshark_import_all_task_filters(struct kshark_context *kshark_ctx,
 				    struct kshark_config_doc *conf);
 
+bool kshark_import_all_cpu_filters(struct kshark_context *kshark_ctx,
+				   struct kshark_config_doc *conf);
+
 bool kshark_import_all_filters(struct kshark_context *kshark_ctx,
 			       struct kshark_config_doc *conf);
 
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 16/17] kernel-shark-qt: Add "Hide CPU" checkbox dialog to the Main window menu
  2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
                   ` (14 preceding siblings ...)
  2018-11-28 15:16 ` [PATCH 15/17] kernel-shark-qt: Add the CPU filters to the Json config I/O Yordan Karadzhov
@ 2018-11-28 15:16 ` Yordan Karadzhov
  2018-11-28 17:16   ` Steven Rostedt
  2018-11-28 15:16 ` [PATCH 17/17] kernel-shark-qt: Add the user filter mask to the Json config I/O Yordan Karadzhov
  16 siblings, 1 reply; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

"Hide CPU" checkbox dialog is added to Menu/Filtering. This dialog is
complementary to the "Hide CPU" action of the Quick Context Menu.

Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
 kernel-shark-qt/src/KsMainWindow.cpp | 39 ++++++++++++++++++++++++++++
 kernel-shark-qt/src/KsMainWindow.hpp |  4 +++
 2 files changed, 43 insertions(+)

diff --git a/kernel-shark-qt/src/KsMainWindow.cpp b/kernel-shark-qt/src/KsMainWindow.cpp
index f4804bd..16ba8bb 100644
--- a/kernel-shark-qt/src/KsMainWindow.cpp
+++ b/kernel-shark-qt/src/KsMainWindow.cpp
@@ -54,6 +54,7 @@ KsMainWindow::KsMainWindow(QWidget *parent)
   _showEventsAction("Show events", this),
   _showTasksAction("Show tasks", this),
   _hideTasksAction("Hide tasks", this),
+  _hideCPUsAction("Hide CPUs", this),
   _advanceFilterAction("Advance Filtering", this),
   _clearAllFilters("Clear all filters", this),
   _cpuSelectAction("CPUs", this),
@@ -207,6 +208,9 @@ void KsMainWindow::_createActions()
 	connect(&_hideTasksAction,	&QAction::triggered,
 		this,			&KsMainWindow::_hideTasks);
 
+	connect(&_hideCPUsAction,	&QAction::triggered,
+		this,			&KsMainWindow::_hideCPUs);
+
 	connect(&_advanceFilterAction,	&QAction::triggered,
 		this,			&KsMainWindow::_advancedFiltering);
 
@@ -329,6 +333,7 @@ void KsMainWindow::_createMenus()
 	filter->addAction(&_showEventsAction);
 	filter->addAction(&_showTasksAction);
 	filter->addAction(&_hideTasksAction);
+	filter->addAction(&_hideCPUsAction);
 	filter->addAction(&_advanceFilterAction);
 	filter->addAction(&_clearAllFilters);
 
@@ -603,6 +608,40 @@ void KsMainWindow::_hideTasks()
 	dialog->show();
 }
 
+void KsMainWindow::_hideCPUs()
+{
+	kshark_context *kshark_ctx(nullptr);
+	KsCheckBoxWidget *cpu_cbd;
+	KsCheckBoxDialog *dialog;
+
+	if (!kshark_instance(&kshark_ctx))
+		return;
+
+	cpu_cbd = new KsCPUCheckBoxWidget(_data.tep(), this);
+	dialog = new KsCheckBoxDialog(cpu_cbd, this);
+
+	if (!kshark_ctx->hide_cpu_filter ||
+	    !kshark_ctx->hide_cpu_filter->count) {
+		cpu_cbd->setDefault(false);
+	} else {
+		int nCPUs = tep_get_cpus(_data.tep());
+		QVector<bool> v(nCPUs, false);
+
+		for (int i = 0; i < nCPUs; ++i) {
+			if (tracecmd_filter_id_find(kshark_ctx->hide_cpu_filter,
+						    i))
+				v[i] = true;
+		}
+
+		cpu_cbd->set(v);
+	}
+
+	connect(dialog,		&KsCheckBoxDialog::apply,
+		&_data,		&KsDataStore::applyNegCPUFilter);
+
+	dialog->show();
+}
+
 void KsMainWindow::_advancedFiltering()
 {
 	KsAdvFilteringDialog *dialog;
diff --git a/kernel-shark-qt/src/KsMainWindow.hpp b/kernel-shark-qt/src/KsMainWindow.hpp
index 5938a25..b231b52 100644
--- a/kernel-shark-qt/src/KsMainWindow.hpp
+++ b/kernel-shark-qt/src/KsMainWindow.hpp
@@ -120,6 +120,8 @@ private:
 
 	QAction		_hideTasksAction;
 
+	QAction		_hideCPUsAction;
+
 	QAction		_advanceFilterAction;
 
 	QAction		_clearAllFilters;
@@ -171,6 +173,8 @@ private:
 
 	void _hideTasks();
 
+	void _hideCPUs();
+
 	void _advancedFiltering();
 
 	void _clearFilters();
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 17/17] kernel-shark-qt: Add the user filter mask to the Json config I/O
  2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
                   ` (15 preceding siblings ...)
  2018-11-28 15:16 ` [PATCH 16/17] kernel-shark-qt: Add "Hide CPU" checkbox dialog to the Main window menu Yordan Karadzhov
@ 2018-11-28 15:16 ` Yordan Karadzhov
  16 siblings, 0 replies; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-28 15:16 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel

This patch updates the Json config I/O, making possible to
import/export the value of the user filter mask. When the filters
are imported, the states of the "Apply filters to Graph" and
"Apply filters to List" check-boxes are updated accordingly.

Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
---
 kernel-shark-qt/src/KsMainWindow.cpp     | 35 ++++++---
 kernel-shark-qt/src/KsMainWindow.hpp     |  6 ++
 kernel-shark-qt/src/libkshark-configio.c | 99 ++++++++++++++++++++++++
 kernel-shark-qt/src/libkshark.h          | 11 +++
 4 files changed, 142 insertions(+), 9 deletions(-)

diff --git a/kernel-shark-qt/src/KsMainWindow.cpp b/kernel-shark-qt/src/KsMainWindow.cpp
index 16ba8bb..7213c01 100644
--- a/kernel-shark-qt/src/KsMainWindow.cpp
+++ b/kernel-shark-qt/src/KsMainWindow.cpp
@@ -50,7 +50,9 @@ KsMainWindow::KsMainWindow(QWidget *parent)
   _importFilterAction("Import Filter", this),
   _exportFilterAction("Export Filter", this),
   _graphFilterSyncAction(this),
+  _graphFilterSyncCBox(nullptr),
   _listFilterSyncAction(this),
+  _listFilterSyncCBox(nullptr),
   _showEventsAction("Show events", this),
   _showTasksAction("Show tasks", this),
   _hideTasksAction("Hide tasks", this),
@@ -273,7 +275,6 @@ void KsMainWindow::_createMenus()
 {
 	QMenu *file, *sessions, *filter, *plots, *tools, *help;
 	kshark_context *kshark_ctx(nullptr);
-	QCheckBox *cbf2g, *cbf2l;
 
 	if (!kshark_instance(&kshark_ctx))
 		return;
@@ -316,17 +317,17 @@ void KsMainWindow::_createMenus()
 
 	kshark_ctx->filter_mask |= KS_EVENT_VIEW_FILTER_MASK;
 
-	cbf2g = lamMakeCBAction(&_graphFilterSyncAction,
-				"Apply filters to Graph");
+	_graphFilterSyncCBox = lamMakeCBAction(&_graphFilterSyncAction,
+					       "Apply filters to Graph");
 
-	connect(cbf2g,	&QCheckBox::stateChanged,
-		this,	&KsMainWindow::_graphFilterSync);
+	connect(_graphFilterSyncCBox,	&QCheckBox::stateChanged,
+		this,			&KsMainWindow::_graphFilterSync);
 
-	cbf2l = lamMakeCBAction(&_listFilterSyncAction,
-				"Apply filters to List");
+	_listFilterSyncCBox = lamMakeCBAction(&_listFilterSyncAction,
+					      "Apply filters to List");
 
-	connect(cbf2l,	&QCheckBox::stateChanged,
-		this,	&KsMainWindow::_listFilterSync);
+	connect(_listFilterSyncCBox,	&QCheckBox::stateChanged,
+		this,			&KsMainWindow::_listFilterSync);
 
 	filter->addAction(&_graphFilterSyncAction);
 	filter->addAction(&_listFilterSyncAction);
@@ -431,6 +432,20 @@ void KsMainWindow::_exportSession()
 	_session.exportToFile(fileName);
 }
 
+void KsMainWindow::_filterSyncCBoxUpdate(kshark_context *kshark_ctx)
+{
+	if (kshark_ctx->filter_mask & KS_TEXT_VIEW_FILTER_MASK)
+		_listFilterSyncCBox->setChecked(true);
+	else
+		_listFilterSyncCBox->setChecked(false);
+
+	if (kshark_ctx->filter_mask &
+	    (KS_GRAPH_VIEW_FILTER_MASK | KS_EVENT_VIEW_FILTER_MASK))
+		_graphFilterSyncCBox->setChecked(true);
+	else
+		_graphFilterSyncCBox->setChecked(false);
+}
+
 void KsMainWindow::_importFilter()
 {
 	kshark_context *kshark_ctx(nullptr);
@@ -455,6 +470,7 @@ void KsMainWindow::_importFilter()
 	kshark_free_config_doc(conf);
 
 	kshark_filter_entries(kshark_ctx, _data.rows(), _data.size());
+	_filterSyncCBoxUpdate(kshark_ctx);
 	emit _data.updateWidgets(&_data);
 }
 
@@ -960,6 +976,7 @@ void KsMainWindow::loadSession(const QString &fileName)
 	pb.setValue(20);
 
 	_session.loadFilters(kshark_ctx, &_data);
+	_filterSyncCBoxUpdate(kshark_ctx);
 	pb.setValue(130);
 
 	_session.loadSplitterSize(&_splitter);
diff --git a/kernel-shark-qt/src/KsMainWindow.hpp b/kernel-shark-qt/src/KsMainWindow.hpp
index b231b52..72f7059 100644
--- a/kernel-shark-qt/src/KsMainWindow.hpp
+++ b/kernel-shark-qt/src/KsMainWindow.hpp
@@ -112,8 +112,12 @@ private:
 
 	QWidgetAction	_graphFilterSyncAction;
 
+	QCheckBox	*_graphFilterSyncCBox;
+
 	QWidgetAction	_listFilterSyncAction;
 
+	QCheckBox	*_listFilterSyncCBox;
+
 	QAction		_showEventsAction;
 
 	QAction		_showTasksAction;
@@ -218,6 +222,8 @@ private:
 
 	void _deselect();
 
+	void _filterSyncCBoxUpdate(kshark_context *kshark_ctx);
+
 private slots:
 	void _captureFinished(int, QProcess::ExitStatus);
 };
diff --git a/kernel-shark-qt/src/libkshark-configio.c b/kernel-shark-qt/src/libkshark-configio.c
index a426e48..4fe7de3 100644
--- a/kernel-shark-qt/src/libkshark-configio.c
+++ b/kernel-shark-qt/src/libkshark-configio.c
@@ -1201,6 +1201,103 @@ bool kshark_import_adv_filters(struct kshark_context *kshark_ctx,
 	}
 }
 
+static bool kshark_user_mask_to_json(struct kshark_context *kshark_ctx,
+				     struct json_object *jobj)
+{
+	uint8_t mask = kshark_ctx->filter_mask;
+	json_object *jmask;
+
+	jmask = json_object_new_int((int) mask);
+	if (!jmask)
+		return false;
+
+	/* Add the mask to the filter config document. */
+	json_object_object_add(jobj, KS_USER_FILTER_MASK_NAME, jmask);
+	return true;
+}
+
+/**
+ * @brief Record the current value of the the user-specified filter mask into
+ *	  a Configuration document.
+ *
+ * @param kshark_ctx: Input location for session context pointer.
+ * @param conf: Input location for the kshark_config_doc instance. Currently
+ *		only Json format is supported. If NULL, a new Adv. Filter
+ *		Configuration document will be created.
+ *
+ * @returns True on success, otherwise False.
+ */
+bool kshark_export_user_mask(struct kshark_context *kshark_ctx,
+			     struct kshark_config_doc **conf)
+{
+	if (!*conf)
+		*conf = kshark_filter_config_new(KS_CONFIG_JSON);
+
+	if (!*conf)
+		return false;
+
+	switch ((*conf)->format) {
+	case KS_CONFIG_JSON:
+		return kshark_user_mask_to_json(kshark_ctx,
+						(*conf)->conf_doc);
+
+	default:
+		fprintf(stderr, "Document format %d not supported\n",
+			(*conf)->format);
+		return false;
+	}
+}
+
+static bool kshark_user_mask_from_json(struct kshark_context *kshark_ctx,
+				       struct json_object *jobj)
+{
+	json_object *jmask;
+	uint8_t mask;
+
+	if (!kshark_json_type_check(jobj, "kshark.config.filter"))
+		return false;
+	/*
+	 * Use the name of the filter to find the value of the filter maks.
+	 * Notice that the filter config document may contain no data for
+	 * the mask.
+	 */
+	if (!json_object_object_get_ex(jobj, KS_USER_FILTER_MASK_NAME,
+				       &jmask))
+		return false;
+
+	mask = json_object_get_int(jmask);
+	kshark_ctx->filter_mask = mask;
+
+	return true;
+}
+
+/**
+ * @brief Load from Configuration document the value of the user-specified
+ *	  filter mask.
+ *
+ * @param kshark_ctx: Input location for session context pointer.
+ * @param conf: Input location for the kshark_config_doc instance. Currently
+ *		only Json format is supported.
+ *
+ * @returns True, if a mask has been loaded. If the filter configuration
+ *	    document contains no data for the mask or in a case of an error,
+ *	    the function returns False.
+ */
+bool kshark_import_user_mask(struct kshark_context *kshark_ctx,
+			     struct kshark_config_doc *conf)
+{
+	switch (conf->format) {
+	case KS_CONFIG_JSON:
+		return kshark_user_mask_from_json(kshark_ctx,
+						  conf->conf_doc);
+
+	default:
+		fprintf(stderr, "Document format %d not supported\n",
+			conf->format);
+		return false;
+	}
+}
+
 static bool filter_is_set(struct tracecmd_filter_id *filter)
 {
 	return filter && filter->count;
@@ -1430,6 +1527,7 @@ kshark_export_all_filters(struct kshark_context *kshark_ctx,
 	    !kshark_export_all_event_filters(kshark_ctx, &conf) ||
 	    !kshark_export_all_task_filters(kshark_ctx, &conf) ||
 	    !kshark_export_all_cpu_filters(kshark_ctx, &conf) ||
+	    !kshark_export_user_mask(kshark_ctx, &conf) ||
 	    !kshark_export_adv_filters(kshark_ctx, &conf)) {
 		kshark_free_config_doc(conf);
 		return NULL;
@@ -1456,6 +1554,7 @@ bool kshark_import_all_filters(struct kshark_context *kshark_ctx,
 	ret = kshark_import_all_task_filters(kshark_ctx, conf);
 	ret |= kshark_import_all_cpu_filters(kshark_ctx, conf);
 	ret |= kshark_import_all_event_filters(kshark_ctx, conf);
+	ret |= kshark_import_user_mask(kshark_ctx, conf);
 	ret |= kshark_import_adv_filters(kshark_ctx, conf);
 
 	return ret;
diff --git a/kernel-shark-qt/src/libkshark.h b/kernel-shark-qt/src/libkshark.h
index 6a3eba6..b3bd646 100644
--- a/kernel-shark-qt/src/libkshark.h
+++ b/kernel-shark-qt/src/libkshark.h
@@ -504,6 +504,11 @@ enum kshark_config_formats {
  */
 #define KS_ADV_EVENT_FILTER_NAME	"adv event filter"
 
+/**
+ * Field name for the Configuration document describing user-specified filter
+ * mask.
+ */
+#define KS_USER_FILTER_MASK_NAME	"filter mask"
 /**
  * Field name for the Configuration document describing the state of the Vis.
  * model.
@@ -575,6 +580,12 @@ bool kshark_import_event_filter(struct tep_handle *pevent,
 				const char *filter_name,
 				struct kshark_config_doc *conf);
 
+bool kshark_export_user_mask(struct kshark_context *kshark_ctx,
+			     struct kshark_config_doc **conf);
+
+bool kshark_import_user_mask(struct kshark_context *kshark_ctx,
+			     struct kshark_config_doc *conf);
+
 bool kshark_export_filter_array(struct tracecmd_filter_id *filter,
 				const char *filter_name,
 				struct kshark_config_doc *conf);
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 11/17] kernel-shark-qt: Sort all graphs before plotting
  2018-11-28 15:16 ` [PATCH 11/17] kernel-shark-qt: Sort all graphs before plotting Yordan Karadzhov
@ 2018-11-28 17:12   ` Steven Rostedt
  2018-11-29 11:29     ` Yordan Karadzhov
  0 siblings, 1 reply; 21+ messages in thread
From: Steven Rostedt @ 2018-11-28 17:12 UTC (permalink / raw)
  To: Yordan Karadzhov; +Cc: linux-trace-devel

On Wed, 28 Nov 2018 15:16:20 +0000
Yordan Karadzhov <ykaradzhov@vmware.com> wrote:

> The CPU/Task graphs are plotted in sorted order. The graph
> having smallest CPU id/Pid will be plotted first (on top).

I'm fine with this. But I'm wondering if we want to allow the user to
move the plots in the future, if that would be a big design change or
not.

-- Steve

> 
> Signed-off-by: Yordan Karadzhov <ykaradzhov@vmware.com>
> ---
>  kernel-shark-qt/src/KsTraceGraph.cpp | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/kernel-shark-qt/src/KsTraceGraph.cpp b/kernel-shark-qt/src/KsTraceGraph.cpp
> index 09b322a..0b5a8b1 100644
> --- a/kernel-shark-qt/src/KsTraceGraph.cpp
> +++ b/kernel-shark-qt/src/KsTraceGraph.cpp
> @@ -439,6 +439,7 @@ void KsTraceGraph::addCPUPlot(int cpu)
>  		return;
>  
>  	_glWindow._cpuList.append(cpu);
> +	qSort(_glWindow._cpuList);
>  	_selfUpdate();
>  }
>  
> @@ -449,6 +450,7 @@ void KsTraceGraph::addTaskPlot(int pid)
>  		return;
>  
>  	_glWindow._taskList.append(pid);
> +	qSort(_glWindow._taskList);
>  	_selfUpdate();
>  }
>  

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 16/17] kernel-shark-qt: Add "Hide CPU" checkbox dialog to the Main window menu
  2018-11-28 15:16 ` [PATCH 16/17] kernel-shark-qt: Add "Hide CPU" checkbox dialog to the Main window menu Yordan Karadzhov
@ 2018-11-28 17:16   ` Steven Rostedt
  0 siblings, 0 replies; 21+ messages in thread
From: Steven Rostedt @ 2018-11-28 17:16 UTC (permalink / raw)
  To: Yordan Karadzhov; +Cc: linux-trace-devel

On Wed, 28 Nov 2018 15:16:27 +0000
Yordan Karadzhov <ykaradzhov@vmware.com> wrote:


> +void KsMainWindow::_hideCPUs()
> +{
> +	kshark_context *kshark_ctx(nullptr);
> +	KsCheckBoxWidget *cpu_cbd;
> +	KsCheckBoxDialog *dialog;
> +
> +	if (!kshark_instance(&kshark_ctx))
> +		return;
> +
> +	cpu_cbd = new KsCPUCheckBoxWidget(_data.tep(), this);
> +	dialog = new KsCheckBoxDialog(cpu_cbd, this);
> +
> +	if (!kshark_ctx->hide_cpu_filter ||
> +	    !kshark_ctx->hide_cpu_filter->count) {
> +		cpu_cbd->setDefault(false);
> +	} else {
> +		int nCPUs = tep_get_cpus(_data.tep());
> +		QVector<bool> v(nCPUs, false);
> +
> +		for (int i = 0; i < nCPUs; ++i) {
> +			if (tracecmd_filter_id_find(kshark_ctx->hide_cpu_filter,
> +						    i))

Just a nit, but really that "i))" could have been on the previous line.

No need to send another patch, but let's not get too crazy at breaking
up lines like this ;-)

-- Steve

> +				v[i] = true;
> +		}
>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 11/17] kernel-shark-qt: Sort all graphs before plotting
  2018-11-28 17:12   ` Steven Rostedt
@ 2018-11-29 11:29     ` Yordan Karadzhov
  0 siblings, 0 replies; 21+ messages in thread
From: Yordan Karadzhov @ 2018-11-29 11:29 UTC (permalink / raw)
  To: Steven Rostedt; +Cc: linux-trace-devel



On 28.11.18 г. 19:12 ч., Steven Rostedt wrote:
> On Wed, 28 Nov 2018 15:16:20 +0000
> Yordan Karadzhov<ykaradzhov@vmware.com>  wrote:
> 
>> The CPU/Task graphs are plotted in sorted order. The graph
>> having smallest CPU id/Pid will be plotted first (on top).
> I'm fine with this. But I'm wondering if we want to allow the user to
> move the plots in the future, if that would be a big design change or
> not.
> 

Hi Steve,

Currently we use the OpenGL widget as one big white canvas and all 
graphs are drawn on it. If we want to be able to move graphs with the 
mouse we have to make each graph a widget. However this will greatly 
complicate everything. Maybe we can think for some kind of menu which 
can change the order of the graphs before drawing?

Thanks!
Yordan


> -- Steve
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2018-11-29 22:34 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-28 15:16 [PATCH 00/17] More modifications and bug fixes toward KS 1.0 Yordan Karadzhov
2018-11-28 15:16 ` [PATCH 01/17] kernel-shark-qt: Updata Event filter mask when applaing filters to Graph Yordan Karadzhov
2018-11-28 15:16 ` [PATCH 02/17] kernel-shark-qt: Reprocess all CPU collections when the filtering changes Yordan Karadzhov
2018-11-28 15:16 ` [PATCH 03/17] kernel-shark-qt: Fix a byg in unset_event_filter_flag() Yordan Karadzhov
2018-11-28 15:16 ` [PATCH 04/17] kernel-shark qt: No error when Record authentication dialog is closed Yordan Karadzhov
2018-11-28 15:16 ` [PATCH 05/17] kernel-shark-qt: Protect all calls of tep_read_number_field() Yordan Karadzhov
2018-11-28 15:16 ` [PATCH 06/17] kernel-shark-qt: Ignore sched_wakeup events if the task is running Yordan Karadzhov
2018-11-28 15:16 ` [PATCH 07/17] kernel-shark-qt: Fix the documentation of libkshark-model Yordan Karadzhov
2018-11-28 15:16 ` [PATCH 08/17] kernel-shark-qt: Add a method for easy retrieve of all Ids of a filter Yordan Karadzhov
2018-11-28 15:16 ` [PATCH 09/17] kernel-shark-qt: Add centralized context menu for View and Graph widgets Yordan Karadzhov
2018-11-28 15:16 ` [PATCH 10/17] kernel-shark-qt: Add keyboard shortcuts for deselecting the marker Yordan Karadzhov
2018-11-28 15:16 ` [PATCH 11/17] kernel-shark-qt: Sort all graphs before plotting Yordan Karadzhov
2018-11-28 17:12   ` Steven Rostedt
2018-11-29 11:29     ` Yordan Karadzhov
2018-11-28 15:16 ` [PATCH 12/17] kernel-shark-qt: Add CPU-based filtering to the C API Yordan Karadzhov
2018-11-28 15:16 ` [PATCH 13/17] kernel-shark-qt: Add CPU-based filtering to KsDataStore Yordan Karadzhov
2018-11-28 15:16 ` [PATCH 14/17] kernel-shark-qt: Add Hide CPU action to the Quick Context Menu Yordan Karadzhov
2018-11-28 15:16 ` [PATCH 15/17] kernel-shark-qt: Add the CPU filters to the Json config I/O Yordan Karadzhov
2018-11-28 15:16 ` [PATCH 16/17] kernel-shark-qt: Add "Hide CPU" checkbox dialog to the Main window menu Yordan Karadzhov
2018-11-28 17:16   ` Steven Rostedt
2018-11-28 15:16 ` [PATCH 17/17] kernel-shark-qt: Add the user filter mask to the Json config I/O Yordan Karadzhov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).