All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yordan Karadzhov <ykaradzhov@vmware.com>
To: "rostedt@goodmis.org" <rostedt@goodmis.org>
Cc: "linux-trace-devel@vger.kernel.org"
	<linux-trace-devel@vger.kernel.org>,
	Yordan Karadzhov <y.karadz@gmail.com>
Subject: [PATCH v3 2/4] kernel-shark-qt: Add KernalShark Utils
Date: Thu, 11 Oct 2018 16:57:40 +0000	[thread overview]
Message-ID: <20181011165713.15257-3-ykaradzhov@vmware.com> (raw)
In-Reply-To: <20181011165713.15257-1-ykaradzhov@vmware.com>

From: Yordan Karadzhov (VMware) <y.karadz@gmail.com>

This patch introduces the kshark-gui library and defines some basic
components, like Data Store and Plugin Manager, used under the hood
of the KernelShark GUI.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 kernel-shark-qt/build/deff.h.cmake |  16 +
 kernel-shark-qt/src/CMakeLists.txt |  20 +
 kernel-shark-qt/src/KsUtils.cpp    | 594 +++++++++++++++++++++++++++++
 kernel-shark-qt/src/KsUtils.hpp    | 233 +++++++++++
 4 files changed, 863 insertions(+)
 create mode 100644 kernel-shark-qt/src/KsUtils.cpp
 create mode 100644 kernel-shark-qt/src/KsUtils.hpp

diff --git a/kernel-shark-qt/build/deff.h.cmake b/kernel-shark-qt/build/deff.h.cmake
index 44ea08b..d1a1bb7 100644
--- a/kernel-shark-qt/build/deff.h.cmake
+++ b/kernel-shark-qt/build/deff.h.cmake
@@ -14,7 +14,23 @@
 /** KernelShark source code path. */
 #cmakedefine KS_DIR "@KS_DIR@"
 
+/** KernelShark configuration directory path. */
+#cmakedefine KS_CONF_DIR "@KS_CONF_DIR@"
+
 /** Location of the trace-cmd executable. */
 #cmakedefine TRACECMD_BIN_DIR "@TRACECMD_BIN_DIR@"
 
+#ifdef __cplusplus
+
+	#include <QString>
+
+	/**
+	 * String containing semicolon-separated list of plugin names.
+	 * The plugins to be loaded when KernelShark starts are tagged
+	 * with "default".
+	 */
+	const QString plugins = "@PLUGINS@";
+
+#endif /* __cplusplus */
+
 #endif // _KS_CONFIG_H
diff --git a/kernel-shark-qt/src/CMakeLists.txt b/kernel-shark-qt/src/CMakeLists.txt
index 305cea7..e897e9a 100644
--- a/kernel-shark-qt/src/CMakeLists.txt
+++ b/kernel-shark-qt/src/CMakeLists.txt
@@ -28,6 +28,26 @@ if (OPENGL_FOUND AND GLUT_FOUND)
 
 endif (OPENGL_FOUND AND GLUT_FOUND)
 
+if (Qt5Widgets_FOUND AND Qt5Network_FOUND)
+
+    message(STATUS "libkshark-gui")
+    set (ks-guiLib_hdr  KsUtils.hpp)
+
+    QT5_WRAP_CPP(ks-guiLib_hdr_moc ${ks-guiLib_hdr})
+
+    add_library(kshark-gui  SHARED  ${ks-guiLib_hdr_moc}    KsUtils.cpp)
+
+    target_link_libraries(kshark-gui kshark-plot
+                                     ${CMAKE_DL_LIBS}
+                                     ${TRACEEVENT_LIBRARY}
+                                     ${TRACECMD_LIBRARY}
+                                     Qt5::Widgets
+                                     Qt5::Network)
+
+    set_target_properties(kshark-gui PROPERTIES  SUFFIX ".so.${KS_VERSION_STRING}")
+
+endif (Qt5Widgets_FOUND AND Qt5Network_FOUND)
+
 add_subdirectory(plugins)
 
 configure_file( ${KS_DIR}/build/deff.h.cmake
diff --git a/kernel-shark-qt/src/KsUtils.cpp b/kernel-shark-qt/src/KsUtils.cpp
new file mode 100644
index 0000000..13b648e
--- /dev/null
+++ b/kernel-shark-qt/src/KsUtils.cpp
@@ -0,0 +1,594 @@
+// SPDX-License-Identifier: LGPL-2.1
+
+/*
+ * Copyright (C) 2017 VMware Inc, Yordan Karadzhov <ykaradzhov@vmware.com>
+ */
+
+/**
+ *  @file    KsUtils.cpp
+ *  @brief   KernelShark Utils.
+ */
+
+// KernelShark
+#include "KsUtils.hpp"
+
+namespace KsUtils {
+
+/** @brief Get a sorted vector of Task's Pids. */
+QVector<int> getPidList()
+{
+	kshark_context *kshark_ctx(nullptr);
+	int nTasks, *tempPids;
+	QVector<int> pids;
+
+	if (!kshark_instance(&kshark_ctx))
+		return pids;
+
+	nTasks = kshark_get_task_pids(kshark_ctx, &tempPids);
+	for (int r = 0; r < nTasks; ++r) {
+		pids.append(tempPids[r]);
+	}
+
+	free(tempPids);
+
+	qSort(pids);
+
+	return pids;
+}
+
+/**
+ * Set the bit of the filter mask of the kshark session context responsible
+ * for the visibility of the events in the Table View.
+ */
+void listFilterSync(bool state)
+{
+	kshark_context *kshark_ctx(nullptr);
+
+	if (!kshark_instance(&kshark_ctx))
+		return;
+
+	if (state) {
+		kshark_ctx->filter_mask |= KS_TEXT_VIEW_FILTER_MASK;
+	} else {
+		kshark_ctx->filter_mask &= ~KS_TEXT_VIEW_FILTER_MASK;
+	}
+}
+
+/**
+ * Set the bit of the filter mask of the kshark session context responsible
+ * for the visibility of the events in the Graph View.
+ */
+void graphFilterSync(bool state)
+{
+	kshark_context *kshark_ctx(nullptr);
+
+	if (!kshark_instance(&kshark_ctx))
+		return;
+
+	if (state) {
+		kshark_ctx->filter_mask |= KS_GRAPH_VIEW_FILTER_MASK;
+	} else {
+		kshark_ctx->filter_mask &= ~KS_GRAPH_VIEW_FILTER_MASK;
+	}
+}
+
+/**
+ * @brief Simple CPU matching function to be user for data collections.
+ *
+ * @param kshark_ctx: Input location for the session context pointer.
+ * @param e: kshark_entry to be checked.
+ * @param cpu: Matching condition value.
+ *
+ * @returns True if the CPU of the entry matches the value of "cpu" and
+ * 	    the entry is visibility in Graph. Otherwise false.
+ */
+bool matchCPUVisible(struct kshark_context *kshark_ctx,
+		     struct kshark_entry *e, int cpu)
+{
+	return (e->cpu == cpu && (e->visible & KS_GRAPH_VIEW_FILTER_MASK));
+}
+
+}; // KsUtils
+
+/** A stream operator for converting QColor into KsPlot::Color. */
+KsPlot::Color& operator <<(KsPlot::Color &thisColor, const QColor &c)
+{
+	thisColor.set(c.red(), c.green(), c.blue());
+
+	return thisColor;
+}
+
+/** Create a default (empty) KsDataStore. */
+KsDataStore::KsDataStore(QWidget *parent)
+: QObject(parent),
+  _tep(nullptr),
+  _rows(nullptr),
+  _dataSize(0)
+{}
+
+/** Destroy the KsDataStore object. */
+KsDataStore::~KsDataStore()
+{}
+
+/** Load trace data for file. */
+void KsDataStore::loadDataFile(const QString &file)
+{
+	kshark_context *kshark_ctx(nullptr);
+
+	if (!kshark_instance(&kshark_ctx))
+		return;
+
+	clear();
+
+	if (!kshark_open(kshark_ctx, file.toStdString().c_str())) {
+		qCritical() << "ERROR Loading file " << file;
+		return;
+	}
+
+	_tep = kshark_ctx->pevent;
+
+	if (kshark_ctx->event_handlers == nullptr)
+		kshark_handle_plugins(kshark_ctx, KSHARK_PLUGIN_INIT);
+	else
+		kshark_handle_plugins(kshark_ctx, KSHARK_PLUGIN_UPDATE);
+
+	_dataSize = kshark_load_data_entries(kshark_ctx, &_rows);
+}
+
+void KsDataStore::_freeData()
+{
+	if (_dataSize) {
+		for (size_t r = 0; r < _dataSize; ++r)
+			free(_rows[r]);
+
+		free(_rows);
+		_rows = nullptr;
+	}
+}
+
+/** Reload the trace data. */
+void KsDataStore::reload()
+{
+	kshark_context *kshark_ctx(nullptr);
+
+	if (!kshark_instance(&kshark_ctx))
+		return;
+
+	_freeData();
+
+	_dataSize = kshark_load_data_entries(kshark_ctx, &_rows);
+	_tep = kshark_ctx->pevent;
+
+	emit updateWidgets(this);
+}
+
+/** Free the loaded trace data and close the file. */
+void KsDataStore::clear()
+{
+	kshark_context *kshark_ctx(nullptr);
+
+	_freeData();
+	_tep = nullptr;
+
+	if (kshark_instance(&kshark_ctx) && kshark_ctx->handle)
+		kshark_close(kshark_ctx);
+}
+
+/** Update the visibility of the entries (filter). */
+void KsDataStore::update()
+{
+	kshark_context *kshark_ctx(nullptr);
+
+	if (!kshark_instance(&kshark_ctx))
+		return;
+
+	if (kshark_filter_is_set(kshark_ctx)) {
+		kshark_filter_entries(kshark_ctx, _rows, _dataSize);
+		emit updateWidgets(this);
+	}
+}
+
+/** Register a collection of visible entries for each CPU. */
+void KsDataStore::registerCPUCollections()
+{
+	kshark_context *kshark_ctx(nullptr);
+
+	if (!kshark_instance(&kshark_ctx) ||
+	    !kshark_filter_is_set(kshark_ctx))
+		return;
+
+	int nCPUs = tep_get_cpus(_tep);
+	for (int cpu = 0; cpu < nCPUs; ++cpu) {
+		kshark_register_data_collection(kshark_ctx,
+						_rows, _dataSize,
+						KsUtils::matchCPUVisible,
+						cpu,
+						0);
+	}
+}
+
+void KsDataStore::_unregisterCPUCollections()
+{
+	kshark_context *kshark_ctx(nullptr);
+
+	if (!kshark_instance(&kshark_ctx))
+		return;
+
+	int nCPUs = tep_get_cpus(_tep);
+	for (int cpu = 0; cpu < nCPUs; ++cpu) {
+		kshark_unregister_data_collection(&kshark_ctx->collections,
+						  KsUtils::matchCPUVisible,
+						  cpu);
+	}
+}
+
+void KsDataStore::_applyIdFilter(int filterId, QVector<int> vec)
+{
+	kshark_context *kshark_ctx(nullptr);
+
+	if (!kshark_instance(&kshark_ctx))
+		return;
+
+	switch (filterId) {
+		case KS_SHOW_EVENT_FILTER:
+		case KS_HIDE_EVENT_FILTER:
+			kshark_filter_clear(kshark_ctx, KS_SHOW_EVENT_FILTER);
+			kshark_filter_clear(kshark_ctx, KS_HIDE_EVENT_FILTER);
+			break;
+		case KS_SHOW_TASK_FILTER:
+		case KS_HIDE_TASK_FILTER:
+			kshark_filter_clear(kshark_ctx, KS_SHOW_TASK_FILTER);
+			kshark_filter_clear(kshark_ctx, KS_HIDE_TASK_FILTER);
+			break;
+		default:
+			return;
+	}
+
+	for (auto &&pid: vec)
+		kshark_filter_add_id(kshark_ctx, filterId, pid);
+
+	if (!_tep)
+		return;
+
+	_unregisterCPUCollections();
+
+	/*
+	 * If the advanced event filter is set, the data has to be reloaded,
+	 * because the advanced filter uses tep_records.
+	 */
+	if (kshark_ctx->advanced_event_filter->filters)
+		reload();
+	else
+		kshark_filter_entries(kshark_ctx, _rows, _dataSize);
+
+	registerCPUCollections();
+
+	emit updateWidgets(this);
+}
+
+/** Apply Show Task filter. */
+void KsDataStore::applyPosTaskFilter(QVector<int> vec)
+{
+	_applyIdFilter(KS_SHOW_TASK_FILTER, vec);
+}
+
+/** Apply Hide Task filter. */
+void KsDataStore::applyNegTaskFilter(QVector<int> vec)
+{
+	_applyIdFilter(KS_HIDE_TASK_FILTER, vec);
+}
+
+/** Apply Show Event filter. */
+void KsDataStore::applyPosEventFilter(QVector<int> vec)
+{
+	_applyIdFilter(KS_SHOW_EVENT_FILTER, vec);
+}
+
+/** Apply Hide Event filter. */
+void KsDataStore::applyNegEventFilter(QVector<int> vec)
+{
+	_applyIdFilter(KS_HIDE_EVENT_FILTER, vec);
+}
+
+/** Disable all filters. */
+void KsDataStore::clearAllFilters()
+{
+	kshark_context *kshark_ctx(nullptr);
+
+	if (!kshark_instance(&kshark_ctx) || !_tep)
+		return;
+
+	_unregisterCPUCollections();
+
+	kshark_filter_clear(kshark_ctx, KS_SHOW_TASK_FILTER);
+	kshark_filter_clear(kshark_ctx, KS_HIDE_TASK_FILTER);
+	kshark_filter_clear(kshark_ctx, KS_SHOW_EVENT_FILTER);
+	kshark_filter_clear(kshark_ctx, KS_HIDE_EVENT_FILTER);
+
+	tep_filter_reset(kshark_ctx->advanced_event_filter);
+	kshark_clear_all_filters(kshark_ctx, _rows, _dataSize);
+
+	emit updateWidgets(this);
+}
+
+/**
+ * @brief Create Plugin Manager. Use list of plugins declared in the
+ *	  CMake-generated header file.
+ */
+KsPluginManager::KsPluginManager(QWidget *parent)
+: QObject(parent)
+{
+	kshark_context *kshark_ctx(nullptr);
+	_parsePluginList();
+
+	if (!kshark_instance(&kshark_ctx))
+		return;
+
+	registerFromList(kshark_ctx);
+}
+
+/** Parse the plugin list declared in the CMake-generated header file. */
+void KsPluginManager::_parsePluginList()
+{
+	_ksPluginList = KsUtils::getPluginList();
+	int nPlugins = _ksPluginList.count();
+
+	_registeredKsPlugins.resize(nPlugins);
+	for (int i = 0; i < nPlugins; ++i) {
+		if (_ksPluginList[i].contains(" default", Qt::CaseInsensitive)) {
+			_ksPluginList[i].remove(" default", Qt::CaseInsensitive);
+			_registeredKsPlugins[i] = true;
+		} else {
+			_registeredKsPlugins[i] = false;
+		}
+	}
+}
+
+/**
+ * Register the plugins by using the information in "_ksPluginList" and
+ * "_registeredKsPlugins".
+ */
+void KsPluginManager::registerFromList(kshark_context *kshark_ctx)
+{
+	auto lamRegBuiltIn = [&kshark_ctx](const QString &plugin)
+	{
+		char *lib;
+		int n;
+
+		n = asprintf(&lib, "%s/lib/plugin-%s.so",
+			     KS_DIR, plugin.toStdString().c_str());
+		if (n <= 0)
+			return;
+
+		kshark_register_plugin(kshark_ctx, lib);
+		free(lib);
+	};
+
+	auto lamRegUser = [&kshark_ctx](const QString &plugin)
+	{
+		const char *lib = plugin.toStdString().c_str();
+		kshark_register_plugin(kshark_ctx, lib);
+	};
+
+	_forEachInList(_ksPluginList,
+		       _registeredKsPlugins,
+		       lamRegBuiltIn);
+
+	_forEachInList(_userPluginList,
+		       _registeredUserPlugins,
+		       lamRegUser);
+}
+
+/**
+ * Unegister the plugins by using the information in "_ksPluginList" and
+ * "_registeredKsPlugins".
+ */
+void KsPluginManager::unregisterFromList(kshark_context *kshark_ctx)
+{
+	auto lamUregBuiltIn = [&kshark_ctx](const QString &plugin)
+	{
+		char *lib;
+		int n;
+
+		n = asprintf(&lib, "%s/lib/plugin-%s.so",
+			     KS_DIR, plugin.toStdString().c_str());
+		if (n <= 0)
+			return;
+
+		kshark_unregister_plugin(kshark_ctx, lib);
+		free(lib);
+	};
+
+	auto lamUregUser = [&kshark_ctx](const QString &plugin)
+	{
+		const char *lib = plugin.toStdString().c_str();
+		kshark_unregister_plugin(kshark_ctx, lib);
+	};
+
+	_forEachInList(_ksPluginList,
+		       _registeredKsPlugins,
+			lamUregBuiltIn);
+
+	_forEachInList(_userPluginList,
+		       _registeredUserPlugins,
+			lamUregUser);
+}
+
+/**
+ * @brief Register a Plugin.
+ *
+ * @param plugin: provide here the name of the plugin (as in the CMake-generated
+ *		  header file) of a name of the plugin's library file (.so).
+ */
+void KsPluginManager::registerPlugin(const QString &plugin)
+{
+	kshark_context *kshark_ctx(nullptr);
+	char *lib;
+	int n;
+
+	if (!kshark_instance(&kshark_ctx))
+		return;
+
+	for (int i = 0; i < _ksPluginList.count(); ++i) {
+		if (_ksPluginList[i] == plugin) {
+			/*
+			 * The argument is the name of the plugin. From the
+			 * name get the library .so file.
+			 */
+			n = asprintf(&lib, "%s/lib/plugin-%s.so",
+					KS_DIR, plugin.toStdString().c_str());
+			if (n > 0) {
+				kshark_register_plugin(kshark_ctx, lib);
+				_registeredKsPlugins[i] = true;
+				free(lib);
+			}
+
+			return;
+
+		} else if (plugin.contains("/lib/plugin-" + _ksPluginList[i],
+					   Qt::CaseInsensitive)) {
+			/*
+			 * The argument is the name of the library .so file.
+			 */
+			n = asprintf(&lib, "%s", plugin.toStdString().c_str());
+			if (n > 0) {
+				kshark_register_plugin(kshark_ctx, lib);
+				_registeredKsPlugins[i] = true;
+				free(lib);
+			}
+
+			return;
+		}
+	}
+
+	/* No plugin with this name in the list. Try to add it anyway. */
+	if (plugin.endsWith(".so") && QFileInfo::exists(plugin)) {
+		kshark_register_plugin(kshark_ctx,
+				       plugin.toStdString().c_str());
+
+		_userPluginList.append(plugin);
+		_registeredUserPlugins.append(true);
+	} else {
+		qCritical() << "ERROR: " << plugin << "cannot be registered!";
+	}
+}
+
+/** @brief Unregister a Built in KernelShark plugin.
+ *<br>
+ * WARNING: Do not use this function to unregister User plugins.
+ * Instead use directly kshark_unregister_plugin().
+ *
+ * @param plugin: provide here the name of the plugin (as in the CMake-generated
+ *		  header file) or a name of the plugin's library file (.so).
+ *
+ */
+void KsPluginManager::unregisterPlugin(const QString &plugin)
+{
+	kshark_context *kshark_ctx(nullptr);
+	char *lib;
+	int n;
+
+	if (!kshark_instance(&kshark_ctx))
+		return;
+
+	for (int i = 0; i < _ksPluginList.count(); ++i) {
+		if (_ksPluginList[i] == plugin) {
+			/*
+			 * The argument is the name of the plugin. From the
+			 * name get the library .so file.
+			 */
+			n = asprintf(&lib, "%s/lib/plugin-%s.so", KS_DIR,
+				     plugin.toStdString().c_str());
+			if (n > 0) {
+				kshark_unregister_plugin(kshark_ctx, lib);
+				_registeredKsPlugins[i] = false;
+				free(lib);
+			}
+
+			return;
+		} else if  (plugin.contains("/lib/plugin-" +
+			                   _ksPluginList[i], Qt::CaseInsensitive)) {
+			/*
+			 * The argument is the name of the library .so file.
+			 */
+			n = asprintf(&lib, "%s", plugin.toStdString().c_str());
+			if (n > 0) {
+				kshark_unregister_plugin(kshark_ctx, lib);
+				_registeredKsPlugins[i] = false;
+				free(lib);
+			}
+
+			return;
+		}
+	}
+}
+
+/** Unload all plugins. */
+void KsPluginManager::unloadAll()
+{
+	kshark_context *kshark_ctx(nullptr);
+
+	if (!kshark_instance(&kshark_ctx))
+		return;
+
+	kshark_handle_plugins(kshark_ctx, KSHARK_PLUGIN_CLOSE);
+	kshark_free_plugin_list(kshark_ctx->plugins);
+	kshark_ctx->plugins = nullptr;
+	kshark_free_event_handler_list(kshark_ctx->event_handlers);
+
+	unregisterFromList(kshark_ctx);
+}
+
+/** @brief Update (change) the Plugins.
+ *
+ * @param pluginIds: The indexes of the plugins to be loaded.
+ */
+void KsPluginManager::updatePlugins(QVector<int> pluginIds)
+{
+	kshark_context *kshark_ctx(nullptr);
+
+	if (!kshark_instance(&kshark_ctx))
+		return;
+
+	auto register_plugins = [&] (QVector<int> ids)
+	{
+		int nKsPlugins = _registeredKsPlugins.count();
+
+		/* First clear all registered plugins. */
+		for (auto &p: _registeredKsPlugins)
+			p = false;
+		for (auto &p: _registeredUserPlugins)
+			p = false;
+
+		/* The vector contains the indexes of those to register. */
+		for (auto const &p: ids) {
+			if (p < nKsPlugins)
+				_registeredKsPlugins[p] = true;
+			else
+				_registeredUserPlugins[p - nKsPlugins] = true;
+		}
+		registerFromList(kshark_ctx);
+	};
+
+	if (!kshark_ctx->pevent) {
+		kshark_free_plugin_list(kshark_ctx->plugins);
+		kshark_ctx->plugins = nullptr;
+
+		/*
+		 * No data is loaded. For the moment, just register the
+		 * plugins. Handling of the plugins will be done after
+		 * we load a data file.
+		 */
+		register_plugins(pluginIds);
+		return;
+	}
+
+	/* Clean up all old plugins first. */
+	unloadAll();
+
+	/* Now load. */
+	register_plugins(pluginIds);
+	kshark_handle_plugins(kshark_ctx, KSHARK_PLUGIN_INIT);
+
+	emit dataReload();
+}
diff --git a/kernel-shark-qt/src/KsUtils.hpp b/kernel-shark-qt/src/KsUtils.hpp
new file mode 100644
index 0000000..b14cd6a
--- /dev/null
+++ b/kernel-shark-qt/src/KsUtils.hpp
@@ -0,0 +1,233 @@
+/* SPDX-License-Identifier: LGPL-2.1 */
+
+/*
+ * Copyright (C) 2017 VMware Inc, Yordan Karadzhov <ykaradzhov@vmware.com>
+ */
+
+/**
+ *  @file    KsUtils.hpp
+ *  @brief   KernelShark Utils.
+ */
+
+#ifndef _KS_UTILS_H
+#define _KS_UTILS_H
+
+// C++ 11
+#include <chrono>
+
+// Qt
+#include <QtWidgets>
+
+// KernelShark
+#include "libkshark.h"
+#include "libkshark-model.h"
+#include "KsCmakeDef.hpp"
+#include "KsPlotTools.hpp"
+
+/** Macro providing the height of the screen in pixels. */
+#define SCREEN_HEIGHT  QApplication::desktop()->screenGeometry().height()
+
+/** Macro providing the width of the screen in pixels. */
+#define SCREEN_WIDTH   QApplication::desktop()->screenGeometry().width()
+
+//! @cond Doxygen_Suppress
+
+auto fontHeight = []()
+{
+	QFont font;
+	QFontMetrics fm(font);
+
+	return fm.height();
+};
+
+auto stringWidth = [](QString s)
+{
+	QFont font;
+	QFontMetrics fm(font);
+
+	return fm.width(s);
+};
+
+//! @endcond
+
+/** Macro providing the height of the font in pixels. */
+#define FONT_HEIGHT		fontHeight()
+
+/** Macro providing the width of the font in pixels. */
+#define FONT_WIDTH 		stringWidth("4")
+
+/** Macro providing the width of a string in pixels. */
+#define STRING_WIDTH(s)		stringWidth(s)
+
+/** Macro providing the height of the KernelShark graphs in pixels. */
+#define KS_GRAPH_HEIGHT	(FONT_HEIGHT*2)
+
+//! @cond Doxygen_Suppress
+
+#define KS_JSON_CAST(doc) \
+reinterpret_cast<json_object *>(doc)
+
+#define KS_C_STR_CAST(doc) \
+reinterpret_cast<const char *>(doc)
+
+typedef std::chrono::high_resolution_clock::time_point  hd_time;
+
+#define GET_TIME std::chrono::high_resolution_clock::now()
+
+#define GET_DURATION(t0) \
+std::chrono::duration_cast<std::chrono::duration<double>>( \
+std::chrono::high_resolution_clock::now() - t0).count()
+
+//! @endcond
+
+namespace KsUtils {
+
+QVector<int> getPidList();
+
+/** @brief Geat the list of plugins. */
+inline QStringList getPluginList() {return plugins.split(";");}
+
+void listFilterSync(bool state);
+
+void graphFilterSync(bool state);
+
+/** @brief Convert the timestamp of the trace record into a string showing
+ *	   the time in seconds.
+ *
+ * @param ts: Input location for the timestamp.
+ * @param prec: the number of digits after the decimal point in the return
+ *		string.
+ *
+ * @returns String showing the time in seconds.
+ */
+inline QString Ts2String(int64_t ts, int prec)
+{
+	return QString::number(ts * 1e-9, 'f', prec);
+}
+
+bool matchCPUVisible(struct kshark_context *kshark_ctx,
+			      struct kshark_entry *e, int cpu);
+}; // KsUtils
+
+/** Identifier of the Dual Marker active state. */
+enum class DualMarkerState {
+	A,
+	B
+};
+
+/**
+ * The KsDataStore class provides the access to trace data for all KernelShark
+ * widgets.
+ */
+class KsDataStore : public QObject
+{
+	Q_OBJECT
+public:
+	explicit KsDataStore(QWidget *parent = nullptr);
+
+	~KsDataStore();
+
+	void loadDataFile(const QString &file);
+
+	void clear();
+
+	/** Get the trace event parser. */
+	tep_handle *tep() const {return _tep;}
+
+	/** Get the trace data array.. */
+	struct kshark_entry **rows() const {return _rows;}
+
+	/** Get the size of the data array. */
+	size_t size() const {return _dataSize;}
+
+	void reload();
+
+	void update();
+
+	void registerCPUCollections();
+
+	void applyPosTaskFilter(QVector<int>);
+
+	void applyNegTaskFilter(QVector<int>);
+
+	void applyPosEventFilter(QVector<int>);
+
+	void applyNegEventFilter(QVector<int>);
+
+	void clearAllFilters();
+
+signals:
+	/**
+	 * This signal is emitted when the data has changed and the View
+	 * widgets have to update.
+	 */
+	void updateWidgets(KsDataStore *);
+
+private:
+	/** Page event used to parse the page. */
+	tep_handle		*_tep;
+
+	/** Trace data array. */
+	struct kshark_entry	**_rows;
+
+	/** The size of the data array. */
+	size_t			_dataSize;
+
+	void _freeData();
+	void _unregisterCPUCollections();
+	void _applyIdFilter(int filterId, QVector<int> vec);
+};
+
+/** A Plugin Manage class. */
+class KsPluginManager : public QObject
+{
+	Q_OBJECT
+public:
+	explicit KsPluginManager(QWidget *parent = nullptr);
+
+	/** A list of available built-in plugins. */
+	QStringList	_ksPluginList;
+
+	/** A list of registered built-in plugins. */
+	QVector<bool>	_registeredKsPlugins;
+
+	/** A list of available user plugins. */
+	QStringList	_userPluginList;
+
+	/** A list of registered user plugins. */
+	QVector<bool>	_registeredUserPlugins;
+
+	void registerFromList(kshark_context *kshark_ctx);
+	void unregisterFromList(kshark_context *kshark_ctx);
+
+	void registerPlugin(const QString &plugin);
+	void unregisterPlugin(const QString &plugin);
+	void unloadAll();
+
+	void updatePlugins(QVector<int> pluginId);
+
+signals:
+	/** This signal is emitted when a plugin is loaded or unloaded. */
+	void dataReload();
+
+private:
+	void _parsePluginList();
+
+	template <class T>
+	void _forEachInList(const QStringList &pl,
+			    const QVector<bool> &reg,
+			    T action)
+	{
+		int nPlugins;
+		nPlugins = pl.count();
+		for (int i = 0; i < nPlugins; ++i) {
+			if (reg[i]) {
+				action(pl[i]);
+			}
+		}
+	}
+};
+
+KsPlot::Color& operator <<(KsPlot::Color &thisColor, const QColor &c);
+
+#endif
-- 
2.17.1

  parent reply	other threads:[~2018-10-12  0:25 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-11 16:57 [PATCH v3 0/4] Add basic components to be used by the Qt GUI Yordan Karadzhov
2018-10-11 16:57 ` [PATCH v3 1/4] kernel-shark-qt: Add Qt as a third party dependency Yordan Karadzhov
2018-10-11 16:57 ` Yordan Karadzhov [this message]
2018-10-11 16:57 ` [PATCH v3 3/4] kernel-shark-qt: Add Widgets Lib Yordan Karadzhov
2018-10-11 16:57 ` [PATCH v3 4/4] kernel-shark-qt: Add widget demo example Yordan Karadzhov
2018-10-11 21:15 ` [PATCH v3 0/4] Add basic components to be used by the Qt GUI Steven Rostedt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181011165713.15257-3-ykaradzhov@vmware.com \
    --to=ykaradzhov@vmware.com \
    --cc=linux-trace-devel@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    --cc=y.karadz@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.