Linux-Trace-Devel Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 0/5] kernel-shark: Optimize the logic of the filtering menus
@ 2020-03-19 14:10 Yordan Karadzhov (VMware)
  2020-03-19 14:10 ` [PATCH 1/5] kernel-shark: Add method for checking if a given ID filter is set Yordan Karadzhov (VMware)
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Yordan Karadzhov (VMware) @ 2020-03-19 14:10 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel, Yordan Karadzhov (VMware)

The original motivation for this change was to fix the problem that all
negative ID filters which are set using the Quick Context menu of
KernelSharlk are not visible when you open the main Filtering menus.
The logic of the main menus is optimized to use both type of filtering
and to automatically decide whether is more efficient to set positive
(show only) or negative (do not show) filter. The patch-set also includes
one very simple bug fix (patch 2/5) that was found during the development
of the new filtering logic.


Yordan Karadzhov (VMware) (5):
  kernel-shark: Add method for checking if a given ID filter is set
  kernel-shark: Fix bug in bool kshark_export_all_cpu_filters()
  kernel-shark: Add two helper methods to KsUtils
  kernel-shark: Remove unused methods from KsMainWindow class
  kernel-shark: Optimize the logic of the filtering menus

 kernel-shark/src/KsCaptureDialog.cpp  |   6 +-
 kernel-shark/src/KsMainWindow.cpp     | 229 +++++++++++++++-----------
 kernel-shark/src/KsMainWindow.hpp     |  16 +-
 kernel-shark/src/KsUtils.cpp          |  38 +++++
 kernel-shark/src/KsUtils.hpp          |   4 +
 kernel-shark/src/libkshark-configio.c |  17 +-
 kernel-shark/src/libkshark.c          |  21 ++-
 kernel-shark/src/libkshark.h          |   2 +
 8 files changed, 211 insertions(+), 122 deletions(-)

-- 
2.20.1


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

* [PATCH 1/5] kernel-shark: Add method for checking if a given ID filter is set
  2020-03-19 14:10 [PATCH 0/5] kernel-shark: Optimize the logic of the filtering menus Yordan Karadzhov (VMware)
@ 2020-03-19 14:10 ` Yordan Karadzhov (VMware)
  2020-03-19 14:10 ` [PATCH 2/5] kernel-shark: Fix bug in bool kshark_export_all_cpu_filters() Yordan Karadzhov (VMware)
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Yordan Karadzhov (VMware) @ 2020-03-19 14:10 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel, Yordan Karadzhov (VMware)

The method is already defined and used as a static function in
libkshark.c and libkshark-configio.c (basically having two identical
copies). Now we are making this method part of the API. We will later
use this method in the GUI (following patch).

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 kernel-shark/src/libkshark-configio.c | 17 ++++++-----------
 kernel-shark/src/libkshark.c          | 21 ++++++++++++++-------
 kernel-shark/src/libkshark.h          |  2 ++
 3 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/kernel-shark/src/libkshark-configio.c b/kernel-shark/src/libkshark-configio.c
index 5d7323f..f01a39b 100644
--- a/kernel-shark/src/libkshark-configio.c
+++ b/kernel-shark/src/libkshark-configio.c
@@ -1306,11 +1306,6 @@ bool kshark_import_user_mask(struct kshark_context *kshark_ctx,
 	}
 }
 
-static bool filter_is_set(struct tracecmd_filter_id *filter)
-{
-	return filter && filter->count;
-}
-
 /**
  * @brief Record the current configuration of "show task" and "hide task"
  *	  filters into a Json document.
@@ -1335,13 +1330,13 @@ bool kshark_export_all_event_filters(struct kshark_context *kshark_ctx,
 		return false;
 
 	/* Save a filter only if it contains Id values. */
-	if (filter_is_set(kshark_ctx->show_event_filter))
+	if (kshark_this_filter_is_set(kshark_ctx->show_event_filter))
 		ret &= kshark_export_event_filter(kshark_ctx->pevent,
 						  kshark_ctx->show_event_filter,
 						  KS_SHOW_EVENT_FILTER_NAME,
 						  *conf);
 
-	if (filter_is_set(kshark_ctx->hide_event_filter))
+	if (kshark_this_filter_is_set(kshark_ctx->hide_event_filter))
 		ret &= kshark_export_event_filter(kshark_ctx->pevent,
 						  kshark_ctx->hide_event_filter,
 						  KS_HIDE_EVENT_FILTER_NAME,
@@ -1374,12 +1369,12 @@ bool kshark_export_all_task_filters(struct kshark_context *kshark_ctx,
 		return false;
 
 	/* Save a filter only if it contains Id values. */
-	if (filter_is_set(kshark_ctx->show_task_filter))
+	if (kshark_this_filter_is_set(kshark_ctx->show_task_filter))
 		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))
+	if (kshark_this_filter_is_set(kshark_ctx->hide_task_filter))
 		ret &= kshark_export_filter_array(kshark_ctx->hide_task_filter,
 						  KS_HIDE_TASK_FILTER_NAME,
 						  *conf);
@@ -1412,12 +1407,12 @@ bool kshark_export_all_cpu_filters(struct kshark_context *kshark_ctx,
 		return false;
 
 	/* Save a filter only if it contains Id values. */
-	if (filter_is_set(kshark_ctx->show_task_filter))
+	if (kshark_this_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))
+	if (kshark_this_filter_is_set(kshark_ctx->hide_task_filter))
 		ret &= kshark_export_filter_array(kshark_ctx->hide_cpu_filter,
 						  KS_HIDE_CPU_FILTER_NAME,
 						  *conf);
diff --git a/kernel-shark/src/libkshark.c b/kernel-shark/src/libkshark.c
index a361578..0905359 100644
--- a/kernel-shark/src/libkshark.c
+++ b/kernel-shark/src/libkshark.c
@@ -445,7 +445,14 @@ void kshark_filter_clear(struct kshark_context *kshark_ctx, int filter_id)
 	tracecmd_filter_id_clear(filter);
 }
 
-static bool filter_is_set(struct tracecmd_filter_id *filter)
+/**
+ * @brief Check if a given Id filter is set.
+ *
+ * @param filter: Input location for the Id filster.
+ *
+ * @returns True if the Id filter is set, otherwise False.
+ */
+bool kshark_this_filter_is_set(struct tracecmd_filter_id *filter)
 {
 	return filter && filter->count;
 }
@@ -459,12 +466,12 @@ static bool filter_is_set(struct tracecmd_filter_id *filter)
  */
 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);
+	return kshark_this_filter_is_set(kshark_ctx->show_task_filter) ||
+-              kshark_this_filter_is_set(kshark_ctx->hide_task_filter) ||
+-              kshark_this_filter_is_set(kshark_ctx->show_cpu_filter) ||
+-              kshark_this_filter_is_set(kshark_ctx->hide_cpu_filter) ||
+-              kshark_this_filter_is_set(kshark_ctx->show_event_filter) ||
+-              kshark_this_filter_is_set(kshark_ctx->hide_event_filter);
 }
 
 static inline void unset_event_filter_flag(struct kshark_context *kshark_ctx,
diff --git a/kernel-shark/src/libkshark.h b/kernel-shark/src/libkshark.h
index e795ed4..0d6c50d 100644
--- a/kernel-shark/src/libkshark.h
+++ b/kernel-shark/src/libkshark.h
@@ -261,6 +261,8 @@ void kshark_filter_add_id(struct kshark_context *kshark_ctx,
 
 void kshark_filter_clear(struct kshark_context *kshark_ctx, int filter_id);
 
+bool kshark_this_filter_is_set(struct tracecmd_filter_id *filter);
+
 bool kshark_filter_is_set(struct kshark_context *kshark_ctx);
 
 void kshark_filter_entries(struct kshark_context *kshark_ctx,
-- 
2.20.1


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

* [PATCH 2/5] kernel-shark: Fix bug in bool kshark_export_all_cpu_filters()
  2020-03-19 14:10 [PATCH 0/5] kernel-shark: Optimize the logic of the filtering menus Yordan Karadzhov (VMware)
  2020-03-19 14:10 ` [PATCH 1/5] kernel-shark: Add method for checking if a given ID filter is set Yordan Karadzhov (VMware)
@ 2020-03-19 14:10 ` Yordan Karadzhov (VMware)
  2020-03-19 14:10 ` [PATCH 3/5] kernel-shark: Add two helper methods to KsUtils Yordan Karadzhov (VMware)
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Yordan Karadzhov (VMware) @ 2020-03-19 14:10 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel, Yordan Karadzhov (VMware)

It makes no sense to check if a Task filter is set, before exporting
a CPU filter. This is most probably a copy/paste bug.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 kernel-shark/src/libkshark-configio.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel-shark/src/libkshark-configio.c b/kernel-shark/src/libkshark-configio.c
index f01a39b..cb7ca54 100644
--- a/kernel-shark/src/libkshark-configio.c
+++ b/kernel-shark/src/libkshark-configio.c
@@ -1407,12 +1407,12 @@ bool kshark_export_all_cpu_filters(struct kshark_context *kshark_ctx,
 		return false;
 
 	/* Save a filter only if it contains Id values. */
-	if (kshark_this_filter_is_set(kshark_ctx->show_task_filter))
+	if (kshark_this_filter_is_set(kshark_ctx->show_cpu_filter))
 		ret &= kshark_export_filter_array(kshark_ctx->show_cpu_filter,
 						  KS_SHOW_CPU_FILTER_NAME,
 						  *conf);
 
-	if (kshark_this_filter_is_set(kshark_ctx->hide_task_filter))
+	if (kshark_this_filter_is_set(kshark_ctx->hide_cpu_filter))
 		ret &= kshark_export_filter_array(kshark_ctx->hide_cpu_filter,
 						  KS_HIDE_CPU_FILTER_NAME,
 						  *conf);
-- 
2.20.1


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

* [PATCH 3/5] kernel-shark: Add two helper methods to KsUtils
  2020-03-19 14:10 [PATCH 0/5] kernel-shark: Optimize the logic of the filtering menus Yordan Karadzhov (VMware)
  2020-03-19 14:10 ` [PATCH 1/5] kernel-shark: Add method for checking if a given ID filter is set Yordan Karadzhov (VMware)
  2020-03-19 14:10 ` [PATCH 2/5] kernel-shark: Fix bug in bool kshark_export_all_cpu_filters() Yordan Karadzhov (VMware)
@ 2020-03-19 14:10 ` Yordan Karadzhov (VMware)
  2020-03-19 14:10 ` [PATCH 4/5] kernel-shark: Remove unused methods from KsMainWindow class Yordan Karadzhov (VMware)
  2020-03-19 14:10 ` [PATCH 5/5] kernel-shark: Optimize the logic of the filtering menus Yordan Karadzhov (VMware)
  4 siblings, 0 replies; 6+ messages in thread
From: Yordan Karadzhov (VMware) @ 2020-03-19 14:10 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel, Yordan Karadzhov (VMware)

The methods can be used to easily retrieve a QVector<int> containing
all CPU or Event IDs. We will later use these method in the GUI
(following patch).

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 kernel-shark/src/KsCaptureDialog.cpp |  6 ++---
 kernel-shark/src/KsUtils.cpp         | 38 ++++++++++++++++++++++++++++
 kernel-shark/src/KsUtils.hpp         |  4 +++
 3 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/kernel-shark/src/KsCaptureDialog.cpp b/kernel-shark/src/KsCaptureDialog.cpp
index 69b9944..d6f8014 100644
--- a/kernel-shark/src/KsCaptureDialog.cpp
+++ b/kernel-shark/src/KsCaptureDialog.cpp
@@ -230,7 +230,7 @@ void KsCaptureControl::_importSettings()
 	kshark_config_doc *conf, *jevents, *temp;
 	QVector<bool> v(nEvts, false);
 	tracecmd_filter_id *eventHash;
-	tep_event **events;
+	QVector<int> eventIds;
 	QString fileName;
 
 	auto lamImportError = [this] () {
@@ -238,7 +238,7 @@ void KsCaptureControl::_importSettings()
 	};
 
 	/** Get all available events. */
-	events = tep_list_events(_localTEP, TEP_EVENT_SORT_SYSTEM);
+	eventIds = KsUtils::getEventIdList(TEP_EVENT_SORT_SYSTEM);
 
 	/* Get the configuration document. */
 	fileName = KsUtils::getFile(this, "Import from Filter",
@@ -277,7 +277,7 @@ void KsCaptureControl::_importSettings()
 	}
 
 	for (int i = 0; i < nEvts; ++i) {
-		if (tracecmd_filter_id_find(eventHash, events[i]->id))
+		if (tracecmd_filter_id_find(eventHash, eventIds[i]))
 			v[i] = true;
 	}
 
diff --git a/kernel-shark/src/KsUtils.cpp b/kernel-shark/src/KsUtils.cpp
index e99509f..77d0c7c 100644
--- a/kernel-shark/src/KsUtils.cpp
+++ b/kernel-shark/src/KsUtils.cpp
@@ -15,6 +15,22 @@
 
 namespace KsUtils {
 
+/** @brief Get a sorted vector of CPU Ids. */
+QVector<int> getCPUList()
+{
+	kshark_context *kshark_ctx(nullptr);
+	int nCPUs;
+
+	if (!kshark_instance(&kshark_ctx))
+		return {};
+
+	nCPUs = tep_get_cpus(kshark_ctx->pevent);
+	QVector<int> allCPUs = QVector<int>(nCPUs);
+	std::iota(allCPUs.begin(), allCPUs.end(), 0);
+
+	return allCPUs;
+}
+
 /** @brief Get a sorted vector of Task's Pids. */
 QVector<int> getPidList()
 {
@@ -37,6 +53,28 @@ QVector<int> getPidList()
 	return pids;
 }
 
+/**
+ * @brief Get a sorted vector of Event Ids.
+ */
+QVector<int> getEventIdList(tep_event_sort_type sortType)
+{
+	kshark_context *kshark_ctx(nullptr);
+	tep_event **events;
+	int nEvts;
+
+	if (!kshark_instance(&kshark_ctx))
+		return {};
+
+	nEvts = tep_get_events_count(kshark_ctx->pevent);
+	events = tep_list_events(kshark_ctx->pevent, sortType);
+
+	QVector<int> allEvts(nEvts);
+	for (int i = 0; i < nEvts; ++i)
+		allEvts[i] = events[i]->id;
+
+	return allEvts;
+}
+
 /** @brief Get a sorted vector of Id values of a filter. */
 QVector<int> getFilterIds(tracecmd_filter_id *filter)
 {
diff --git a/kernel-shark/src/KsUtils.hpp b/kernel-shark/src/KsUtils.hpp
index db1bf5e..f44139b 100644
--- a/kernel-shark/src/KsUtils.hpp
+++ b/kernel-shark/src/KsUtils.hpp
@@ -82,8 +82,12 @@ std::chrono::high_resolution_clock::now() - t0).count()
 
 namespace KsUtils {
 
+QVector<int> getCPUList();
+
 QVector<int> getPidList();
 
+QVector<int> getEventIdList(tep_event_sort_type sortType=TEP_EVENT_SORT_ID);
+
 QVector<int> getFilterIds(tracecmd_filter_id *filter);
 
 /** @brief Geat the list of plugins. */
-- 
2.20.1


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

* [PATCH 4/5] kernel-shark: Remove unused methods from KsMainWindow class
  2020-03-19 14:10 [PATCH 0/5] kernel-shark: Optimize the logic of the filtering menus Yordan Karadzhov (VMware)
                   ` (2 preceding siblings ...)
  2020-03-19 14:10 ` [PATCH 3/5] kernel-shark: Add two helper methods to KsUtils Yordan Karadzhov (VMware)
@ 2020-03-19 14:10 ` Yordan Karadzhov (VMware)
  2020-03-19 14:10 ` [PATCH 5/5] kernel-shark: Optimize the logic of the filtering menus Yordan Karadzhov (VMware)
  4 siblings, 0 replies; 6+ messages in thread
From: Yordan Karadzhov (VMware) @ 2020-03-19 14:10 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel, Yordan Karadzhov (VMware)

We used to have menu actions for applying negative ID filters (do not
show) for PIDs and CPU IDs. At some point we decided to remove all menu
actions for negative filters in order to avoid users being confused by
the possible unexpected behavior in the case when both positive (show
only) and negative filters are set. However we kept the corresponding
private methods, just in case we want to restore the menu actions in
the future. We can now finally remove those methods, because in the
following patch the logic will be optimized to automatically decide
whether is more efficient to use positive or negative filter.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 kernel-shark/src/KsMainWindow.cpp | 69 -------------------------------
 kernel-shark/src/KsMainWindow.hpp |  4 --
 2 files changed, 73 deletions(-)

diff --git a/kernel-shark/src/KsMainWindow.cpp b/kernel-shark/src/KsMainWindow.cpp
index a5a399c..9b5fc2d 100644
--- a/kernel-shark/src/KsMainWindow.cpp
+++ b/kernel-shark/src/KsMainWindow.cpp
@@ -669,41 +669,6 @@ void KsMainWindow::_showTasks()
 	dialog->show();
 }
 
-void KsMainWindow::_hideTasks()
-{
-	kshark_context *kshark_ctx(nullptr);
-	KsCheckBoxWidget *tasks_cbd;
-	KsCheckBoxDialog *dialog;
-
-	if (!kshark_instance(&kshark_ctx))
-		return;
-
-	tasks_cbd = new KsTasksCheckBoxWidget(_data.tep(), false, this);
-	dialog = new KsCheckBoxDialog(tasks_cbd, this);
-
-	if (!kshark_ctx->hide_task_filter ||
-	    !kshark_ctx->hide_task_filter->count) {
-		tasks_cbd->setDefault(false);
-	} else {
-		QVector<int> pids = KsUtils::getPidList();
-		int nPids = pids.count();
-		QVector<bool> v(nPids, false);
-
-		for (int i = 0; i < nPids; ++i) {
-			if (tracecmd_filter_id_find(kshark_ctx->hide_task_filter,
-						    pids[i]))
-				v[i] = true;
-		}
-
-		tasks_cbd->set(v);
-	}
-
-	connect(dialog,		&KsCheckBoxDialog::apply,
-		&_data,		&KsDataStore::applyNegTaskFilter);
-
-	dialog->show();
-}
-
 void KsMainWindow::_showCPUs()
 {
 	kshark_context *kshark_ctx(nullptr);
@@ -737,40 +702,6 @@ void KsMainWindow::_showCPUs()
 	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/src/KsMainWindow.hpp b/kernel-shark/src/KsMainWindow.hpp
index eef4f96..59030e4 100644
--- a/kernel-shark/src/KsMainWindow.hpp
+++ b/kernel-shark/src/KsMainWindow.hpp
@@ -181,12 +181,8 @@ private:
 
 	void _showTasks();
 
-	void _hideTasks();
-
 	void _showCPUs();
 
-	void _hideCPUs();
-
 	void _advancedFiltering();
 
 	void _clearFilters();
-- 
2.20.1


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

* [PATCH 5/5] kernel-shark: Optimize the logic of the filtering menus
  2020-03-19 14:10 [PATCH 0/5] kernel-shark: Optimize the logic of the filtering menus Yordan Karadzhov (VMware)
                   ` (3 preceding siblings ...)
  2020-03-19 14:10 ` [PATCH 4/5] kernel-shark: Remove unused methods from KsMainWindow class Yordan Karadzhov (VMware)
@ 2020-03-19 14:10 ` Yordan Karadzhov (VMware)
  4 siblings, 0 replies; 6+ messages in thread
From: Yordan Karadzhov (VMware) @ 2020-03-19 14:10 UTC (permalink / raw)
  To: rostedt; +Cc: linux-trace-devel, Yordan Karadzhov (VMware)

The logic of the menus is optimized to automatically decide whether is
more efficient to use positive (show only) or negative (do not show)
ID filter. Note that there is no difference between using positive or
negative filters in terms of performance, because the IDs of each filter
are stored in a hash table, hence the checks are made in constant time.
The motivation is just to keep the configuration of the filters as
simple as possible, in particular when we want this configuration to be
saved and later restored from the Session. The patch also fixes the
problem of negative filters set from the Quick Context menu not being
shown in the main filtering menus.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 kernel-shark/src/KsMainWindow.cpp | 184 +++++++++++++++++++++++-------
 kernel-shark/src/KsMainWindow.hpp |  12 ++
 2 files changed, 156 insertions(+), 40 deletions(-)

diff --git a/kernel-shark/src/KsMainWindow.cpp b/kernel-shark/src/KsMainWindow.cpp
index 9b5fc2d..aed28a8 100644
--- a/kernel-shark/src/KsMainWindow.cpp
+++ b/kernel-shark/src/KsMainWindow.cpp
@@ -594,114 +594,218 @@ void KsMainWindow::_graphFilterSync(int state)
 	_data.update();
 }
 
+QVector<bool> KsMainWindow::_getFilterCbStatus(tracecmd_filter_id *showFilter,
+					       tracecmd_filter_id *hideFilter,
+					       QVector<int> ids)
+{
+	QVector<bool> v;
+
+	if (!kshark_this_filter_is_set(showFilter) &&
+	    !kshark_this_filter_is_set(hideFilter)) {
+		return v;
+	} else {
+		int n = ids.count();
+		bool show, hide;
+
+		if (kshark_this_filter_is_set(showFilter)) {
+			/*
+			 * The "show only" filter is set. The default status
+			 * of all CheckBoxes will be "unchecked".
+			 */
+			v = QVector<bool>(n, false);
+			for (int i = 0; i < n; ++i) {
+				show = !!tracecmd_filter_id_find(showFilter,
+								 ids[i]);
+
+				hide = !!tracecmd_filter_id_find(hideFilter,
+								 ids[i]);
+
+				if (show && !hide) {
+					/*
+					 * Both "show" and "hide" define this
+					 * Id as visible. Set the status of
+					 * its CheckBoxes to "checked".
+					 */
+					v[i] = true;
+				}
+			}
+		} else { // Only hide filter is set.
+			v = QVector<bool>(n, true);
+			for (int i = 0; i < n; ++i) {
+				hide = !!tracecmd_filter_id_find(hideFilter,
+								 ids[i]);
+
+				if (hide)
+					v[i] = false;
+			}
+		}
+	}
+
+	return v;
+}
+
+QVector<int> KsMainWindow::_revertFilterIds(QVector<int> all, QVector<int> vec)
+{
+	QVector<int> diff;
+
+	/*
+	 * The Ids may not be sorted, becausein in the widgets the items are
+	 * shown sorted by name. Get those Ids sorted first.
+	 */
+	std::sort(vec.begin(), vec.end());
+
+	/*
+	 * The IDs of the "do not show" filter are given by the difference
+	 * between "all Ids" and the "show only" filter.
+	 */
+	std::set_difference(all.begin(), all.end(),
+			    vec.begin(), vec.end(),
+			    std::inserter(diff, diff.begin()));
+
+	return diff;
+}
+
 void KsMainWindow::_showEvents()
 {
 	kshark_context *kshark_ctx(nullptr);
 	KsCheckBoxWidget *events_cb;
 	KsCheckBoxDialog *dialog;
+	QVector<bool> v;
 
 	if (!kshark_instance(&kshark_ctx))
 		return;
 
 	events_cb = new KsEventsCheckBoxWidget(_data.tep(), this);
 	dialog = new KsCheckBoxDialog(events_cb, this);
+	v = _getFilterCbStatus(kshark_ctx->show_event_filter,
+			       kshark_ctx->hide_event_filter,
+			       KsUtils::getEventIdList(TEP_EVENT_SORT_SYSTEM));
 
-	if (!kshark_ctx->show_event_filter ||
-	    !kshark_ctx->show_event_filter->count) {
+	if (v.count() == 0) {
 		events_cb->setDefault(true);
 	} else {
 		/*
-		 * The event filter contains IDs. Make this visible in the
-		 * CheckBox Widget.
+		 * Some of the event filters contains IDs. Make this visible
+		 * in the CheckBox Widget.
 		 */
-		tep_event **events =
-			tep_list_events(_data.tep(), TEP_EVENT_SORT_SYSTEM);
-		int nEvts = tep_get_events_count(_data.tep());
-		QVector<bool> v(nEvts, false);
-
-		for (int i = 0; i < nEvts; ++i) {
-			if (tracecmd_filter_id_find(kshark_ctx->show_event_filter,
-						    events[i]->id))
-				v[i] = true;
-		}
-
 		events_cb->set(v);
 	}
 
 	connect(dialog,		&KsCheckBoxDialog::apply,
-		&_data,		&KsDataStore::applyPosEventFilter);
+		this,		&KsMainWindow::_applyEventFilter);
 
 	dialog->show();
 }
 
+void KsMainWindow::_applyEventFilter(QVector<int> showEvents)
+{
+	QVector<int> allEvents = KsUtils::getEventIdList();
+
+	if (showEvents.count() < allEvents.count() / 2) {
+		_data.applyPosEventFilter(showEvents);
+	} else {
+		/*
+		 * It is more efficiant to apply negative (do not show) filter.
+		 */
+		QVector<int> diff = _revertFilterIds(allEvents, showEvents);
+		_data.applyNegEventFilter(diff);
+	}
+}
+
 void KsMainWindow::_showTasks()
 {
 	kshark_context *kshark_ctx(nullptr);
 	KsCheckBoxWidget *tasks_cbd;
 	KsCheckBoxDialog *dialog;
+	QVector<bool> v;
 
 	if (!kshark_instance(&kshark_ctx))
 		return;
 
 	tasks_cbd = new KsTasksCheckBoxWidget(_data.tep(), true, this);
 	dialog = new KsCheckBoxDialog(tasks_cbd, this);
+	v = _getFilterCbStatus(kshark_ctx->show_task_filter,
+			       kshark_ctx->hide_task_filter,
+			       KsUtils::getPidList());
 
-	if (!kshark_ctx->show_task_filter ||
-	    !kshark_ctx->show_task_filter->count) {
+	if (v.count() == 0) {
 		tasks_cbd->setDefault(true);
 	} else {
-		QVector<int> pids = KsUtils::getPidList();
-		int nPids = pids.count();
-		QVector<bool> v(nPids, false);
-
-		for (int i = 0; i < nPids; ++i) {
-			if (tracecmd_filter_id_find(kshark_ctx->show_task_filter,
-						    pids[i]))
-				v[i] = true;
-		}
-
+		/*
+		 * Some of the task filters contains PIDs. Make this visible
+		 * in the CheckBox Widget.
+		 */
 		tasks_cbd->set(v);
 	}
 
 	connect(dialog,		&KsCheckBoxDialog::apply,
-		&_data,		&KsDataStore::applyPosTaskFilter);
+		this,		&KsMainWindow::_applyTaskFilter);
 
 	dialog->show();
 }
 
+void KsMainWindow::_applyTaskFilter(QVector<int> showPids)
+{
+	QVector<int> allPids = KsUtils::getPidList();
+
+	if (showPids.count() <  allPids.count() / 2) {
+		_data.applyPosTaskFilter(showPids);
+	} else {
+		/*
+		 * It is more efficiant to apply negative (do not show) filter.
+		 */
+		QVector<int> diff = _revertFilterIds(allPids, showPids);
+		_data.applyNegTaskFilter(diff);
+	}
+}
+
 void KsMainWindow::_showCPUs()
 {
 	kshark_context *kshark_ctx(nullptr);
 	KsCheckBoxWidget *cpu_cbd;
 	KsCheckBoxDialog *dialog;
+	QVector<bool> v;
 
 	if (!kshark_instance(&kshark_ctx))
 		return;
 
 	cpu_cbd = new KsCPUCheckBoxWidget(_data.tep(), this);
 	dialog = new KsCheckBoxDialog(cpu_cbd, this);
+	v = _getFilterCbStatus(kshark_ctx->show_cpu_filter,
+			       kshark_ctx->hide_cpu_filter,
+			       KsUtils::getCPUList());
 
-	if (!kshark_ctx->show_cpu_filter ||
-	    !kshark_ctx->show_cpu_filter->count) {
+	if (v.count() == 0) {
 		cpu_cbd->setDefault(true);
 	} 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->show_cpu_filter, i))
-				v[i] = true;
-		}
-
+		/*
+		 * Some of the CPU filters contains IDs. Make this visible
+		 * in the CheckBox Widget.
+		 */
 		cpu_cbd->set(v);
 	}
 
 	connect(dialog,		&KsCheckBoxDialog::apply,
-		&_data,		&KsDataStore::applyPosCPUFilter);
+		this,		&KsMainWindow::_applyCPUFilter);
 
 	dialog->show();
 }
 
+void KsMainWindow::_applyCPUFilter(QVector<int> showCPUs)
+{
+	QVector<int> allCPUs = KsUtils::getCPUList();
+
+	if (showCPUs.count() < allCPUs.count() / 2) {
+		_data.applyPosCPUFilter(showCPUs);
+	} else {
+		/*
+		 * It is more efficiant to apply negative (do not show) filter.
+		 */
+		QVector<int> diff = _revertFilterIds(allCPUs, showCPUs);
+		_data.applyNegCPUFilter(diff);
+	}
+}
+
 void KsMainWindow::_advancedFiltering()
 {
 	KsAdvFilteringDialog *dialog;
diff --git a/kernel-shark/src/KsMainWindow.hpp b/kernel-shark/src/KsMainWindow.hpp
index 59030e4..ecfc12c 100644
--- a/kernel-shark/src/KsMainWindow.hpp
+++ b/kernel-shark/src/KsMainWindow.hpp
@@ -177,6 +177,18 @@ private:
 
 	void _graphFilterSync(int state);
 
+	QVector<bool> _getFilterCbStatus(tracecmd_filter_id *showFilter,
+					 tracecmd_filter_id *hideFilter,
+					 QVector<int> ids);
+
+	QVector<int> _revertFilterIds(QVector<int> all, QVector<int> vec);
+
+	void _applyEventFilter(QVector<int> showEvents);
+
+	void _applyTaskFilter(QVector<int> showPids);
+
+	void _applyCPUFilter(QVector<int> showCPUs);
+
 	void _showEvents();
 
 	void _showTasks();
-- 
2.20.1


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

end of thread, back to index

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-19 14:10 [PATCH 0/5] kernel-shark: Optimize the logic of the filtering menus Yordan Karadzhov (VMware)
2020-03-19 14:10 ` [PATCH 1/5] kernel-shark: Add method for checking if a given ID filter is set Yordan Karadzhov (VMware)
2020-03-19 14:10 ` [PATCH 2/5] kernel-shark: Fix bug in bool kshark_export_all_cpu_filters() Yordan Karadzhov (VMware)
2020-03-19 14:10 ` [PATCH 3/5] kernel-shark: Add two helper methods to KsUtils Yordan Karadzhov (VMware)
2020-03-19 14:10 ` [PATCH 4/5] kernel-shark: Remove unused methods from KsMainWindow class Yordan Karadzhov (VMware)
2020-03-19 14:10 ` [PATCH 5/5] kernel-shark: Optimize the logic of the filtering menus Yordan Karadzhov (VMware)

Linux-Trace-Devel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-trace-devel/0 linux-trace-devel/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-trace-devel linux-trace-devel/ https://lore.kernel.org/linux-trace-devel \
		linux-trace-devel@vger.kernel.org
	public-inbox-index linux-trace-devel

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-trace-devel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git