sysprof: start on storage section

This commit is contained in:
Christian Hergert
2023-07-25 17:28:58 -07:00
parent 3d836505f0
commit 25f504e6e7
7 changed files with 467 additions and 1 deletions

View File

@ -46,6 +46,7 @@ sysprof_sources = [
'sysprof-sidebar.c',
'sysprof-single-model.c',
'sysprof-split-layer.c',
'sysprof-storage-section.c',
'sysprof-symbol-label.c',
'sysprof-time-filter-model.c',
'sysprof-time-label.c',

View File

@ -0,0 +1,168 @@
/* sysprof-storage-section.c
*
* Copyright 2023 Christian Hergert <chergert@redhat.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "config.h"
#include "sysprof-chart.h"
#include "sysprof-duplex-layer.h"
#include "sysprof-storage-section.h"
#include "sysprof-line-layer.h"
#include "sysprof-pair.h"
#include "sysprof-time-series.h"
#include "sysprof-time-span-layer.h"
#include "sysprof-xy-series.h"
struct _SysprofStorageSection
{
SysprofSection parent_instance;
GListStore *pairs;
};
G_DEFINE_FINAL_TYPE (SysprofStorageSection, sysprof_storage_section, SYSPROF_TYPE_SECTION)
enum {
PROP_0,
PROP_PAIRS,
N_PROPS
};
static GParamSpec *properties[N_PROPS];
static void
sysprof_storage_section_add_pair (SysprofStorageSection *self,
SysprofDocumentCounter *rx,
SysprofDocumentCounter *tx)
{
g_autoptr(SysprofPair) pair = NULL;
g_assert (SYSPROF_IS_STORAGE_SECTION (self));
g_assert (SYSPROF_IS_DOCUMENT_COUNTER (rx));
g_assert (SYSPROF_IS_DOCUMENT_COUNTER (tx));
pair = g_object_new (SYSPROF_TYPE_PAIR,
"first", rx,
"second", tx,
NULL);
g_list_store_append (self->pairs, pair);
}
static void
sysprof_storage_section_session_set (SysprofSection *section,
SysprofSession *session)
{
SysprofStorageSection *self = (SysprofStorageSection *)section;
g_autoptr(GListModel) counters = NULL;
SysprofDocument *document;
guint n_items;
g_assert (SYSPROF_IS_STORAGE_SECTION (self));
g_assert (!session || SYSPROF_IS_SESSION (session));
if (session == NULL)
{
g_list_store_remove_all (self->pairs);
return;
}
document = sysprof_session_get_document (session);
counters = sysprof_document_list_counters (document);
n_items = g_list_model_get_n_items (counters);
for (guint i = 0; i < n_items; i++)
{
g_autoptr(SysprofDocumentCounter) counter = g_list_model_get_item (counters, i);
const char *category = sysprof_document_counter_get_category (counter);
const char *name = sysprof_document_counter_get_name (counter);
if (g_strcmp0 (category, "Disk") == 0 && g_str_has_prefix (name, "Total Reads ("))
{
g_autoptr(SysprofDocumentCounter) writes = NULL;
g_autofree char *alt_name = g_strdup_printf ("Total Writes %s", strchr (name, '('));
if ((writes = sysprof_document_find_counter (document, "Disk", alt_name)))
sysprof_storage_section_add_pair (self, counter, writes);
}
}
}
static void
sysprof_storage_section_dispose (GObject *object)
{
SysprofStorageSection *self = (SysprofStorageSection *)object;
gtk_widget_dispose_template (GTK_WIDGET (self), SYSPROF_TYPE_STORAGE_SECTION);
g_clear_object (&self->pairs);
G_OBJECT_CLASS (sysprof_storage_section_parent_class)->dispose (object);
}
static void
sysprof_storage_section_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
SysprofStorageSection *self = SYSPROF_STORAGE_SECTION (object);
switch (prop_id)
{
case PROP_PAIRS:
g_value_set_object (value, self->pairs);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
}
static void
sysprof_storage_section_class_init (SysprofStorageSectionClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
SysprofSectionClass *section_class = SYSPROF_SECTION_CLASS (klass);
object_class->dispose = sysprof_storage_section_dispose;
object_class->get_property = sysprof_storage_section_get_property;
section_class->session_set = sysprof_storage_section_session_set;
properties [PROP_PAIRS] =
g_param_spec_object ("pairs", NULL, NULL,
G_TYPE_LIST_MODEL,
(G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
g_object_class_install_properties (object_class, N_PROPS, properties);
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/sysprof/sysprof-storage-section.ui");
g_type_ensure (SYSPROF_TYPE_CHART);
g_type_ensure (SYSPROF_TYPE_DUPLEX_LAYER);
g_type_ensure (SYSPROF_TYPE_PAIR);
}
static void
sysprof_storage_section_init (SysprofStorageSection *self)
{
self->pairs = g_list_store_new (SYSPROF_TYPE_PAIR);
gtk_widget_init_template (GTK_WIDGET (self));
}

View File

@ -0,0 +1,33 @@
/* sysprof-storage-section.h
*
* Copyright 2023 Christian Hergert <chergert@redhat.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#pragma once
#include "sysprof-section.h"
G_BEGIN_DECLS
#define SYSPROF_TYPE_STORAGE_SECTION (sysprof_storage_section_get_type())
G_DECLARE_FINAL_TYPE (SysprofStorageSection, sysprof_storage_section, SYSPROF, STORAGE_SECTION, SysprofSection)
G_END_DECLS

View File

@ -0,0 +1,261 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="SysprofStorageSection" parent="SysprofSection">
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="SysprofTimeScrubber" id="scrubber">
<binding name="session">
<lookup name="session">SysprofStorageSection</lookup>
</binding>
<child type="chart">
<object class="SysprofChart">
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="height-request">20</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSeparator"/>
</child>
<child>
<object class="AdwViewStack" id="stack">
<property name="vexpand">true</property>
<child>
<object class="AdwViewStackPage">
<property name="title" translatable="yes">Counters Chart</property>
<property name="icon-name">mark-chart-symbolic</property>
<property name="child">
<object class="GtkScrolledWindow">
<child>
<object class="GtkListView">
<property name="show-separators">true</property>
<property name="model">
<object class="GtkNoSelection">
<property name="model">
<object class="SysprofSessionModel">
<binding name="session">
<lookup name="session">SysprofStorageSection</lookup>
</binding>
<binding name="model">
<lookup name="pairs">SysprofStorageSection</lookup>
</binding>
</object>
</property>
</object>
</property>
<property name="factory">
<object class="GtkBuilderListItemFactory">
<property name="bytes"><![CDATA[
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkBox">
<property name="spacing">12</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
<child>
<object class="GtkInscription">
<property name="vexpand">true</property>
<property name="xalign">1</property>
<property name="min-chars">20</property>
<property name="nat-chars">20</property>
<binding name="text">
<lookup name="name" type="SysprofDocumentCounter">
<lookup name="first" type="SysprofPair">
<lookup name="item" type="SysprofSessionModelItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</lookup>
</lookup>
</binding>
</object>
</child>
<child>
<object class="GtkInscription">
<property name="vexpand">true</property>
<property name="xalign">1</property>
<property name="min-chars">20</property>
<property name="nat-chars">20</property>
<binding name="text">
<lookup name="name" type="SysprofDocumentCounter">
<lookup name="second" type="SysprofPair">
<lookup name="item" type="SysprofSessionModelItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</lookup>
</lookup>
</binding>
</object>
</child>
</object>
</child>
<child>
<object class="SysprofChart">
<property name="hexpand">true</property>
<child>
<object class="SysprofDuplexLayer">
<property name="upper-layer">
<object class="SysprofLineLayer">
<property name="margin-top">1</property>
<property name="margin-bottom">1</property>
<property name="height-request">32</property>
<property name="fill">true</property>
<property name="spline">true</property>
<binding name="x-axis">
<lookup name="selected-time-axis" type="SysprofSession">
<lookup name="session" type="SysprofSessionModelItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</lookup>
</binding>
<property name="y-axis">
<object class="SysprofValueAxis">
<binding name="min-value">
<lookup name="min-value" type="SysprofDocumentCounter">
<lookup name="second" type="SysprofPair">
<lookup name="item" type="SysprofSessionModelItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</lookup>
</lookup>
</binding>
<binding name="max-value">
<lookup name="max-value" type="SysprofDocumentCounter">
<lookup name="second" type="SysprofPair">
<lookup name="item" type="SysprofSessionModelItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</lookup>
</lookup>
</binding>
</object>
</property>
<property name="series">
<object class="SysprofXYSeries">
<binding name="model">
<lookup name="second" type="SysprofPair">
<lookup name="item" type="SysprofSessionModelItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</lookup>
</binding>
<property name="x-expression">
<lookup name="time" type="SysprofDocumentCounterValue"/>
</property>
<property name="y-expression">
<lookup name="value-double" type="SysprofDocumentCounterValue"/>
</property>
</object>
</property>
</object>
</property>
<property name="lower-layer">
<object class="SysprofLineLayer">
<property name="margin-top">1</property>
<property name="margin-bottom">1</property>
<property name="height-request">32</property>
<property name="fill">true</property>
<property name="flip-y">true</property>
<property name="spline">true</property>
<binding name="x-axis">
<lookup name="selected-time-axis" type="SysprofSession">
<lookup name="session" type="SysprofSessionModelItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</lookup>
</binding>
<property name="y-axis">
<object class="SysprofValueAxis">
<binding name="min-value">
<lookup name="min-value" type="SysprofDocumentCounter">
<lookup name="first" type="SysprofPair">
<lookup name="item" type="SysprofSessionModelItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</lookup>
</lookup>
</binding>
<binding name="max-value">
<lookup name="max-value" type="SysprofDocumentCounter">
<lookup name="first" type="SysprofPair">
<lookup name="item" type="SysprofSessionModelItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</lookup>
</lookup>
</binding>
</object>
</property>
<property name="series">
<object class="SysprofXYSeries">
<binding name="model">
<lookup name="first" type="SysprofPair">
<lookup name="item" type="SysprofSessionModelItem">
<lookup name="item">GtkListItem</lookup>
</lookup>
</lookup>
</binding>
<property name="x-expression">
<lookup name="time" type="SysprofDocumentCounterValue"/>
</property>
<property name="y-expression">
<lookup name="value-double" type="SysprofDocumentCounterValue"/>
</property>
</object>
</property>
</object>
</property>
</object>
</child>
</object>
</child>
</object>
</property>
</template>
</interface>
]]>
</property>
</object>
</property>
</object>
</child>
</object>
</property>
</object>
</child>
<child>
<object class="AdwViewStackPage">
<property name="title" translatable="yes">Counters Table</property>
<property name="icon-name">mark-table-symbolic</property>
<property name="child">
<object class="GtkScrolledWindow">
<child>
<object class="GtkColumnView">
</object>
</child>
</object>
</property>
</object>
</child>
</object>
</child>
<child>
<object class="AdwViewSwitcherBar" id="switcher">
<property name="reveal">true</property>
<property name="stack">stack</property>
</object>
</child>
</object>
</child>
</template>
</interface>

View File

@ -34,6 +34,7 @@
#include "sysprof-processes-section.h"
#include "sysprof-samples-section.h"
#include "sysprof-sidebar.h"
#include "sysprof-storage-section.h"
#include "sysprof-window.h"
struct _SysprofWindow
@ -420,6 +421,7 @@ sysprof_window_class_init (SysprofWindowClass *klass)
g_type_ensure (SYSPROF_TYPE_NETWORK_SECTION);
g_type_ensure (SYSPROF_TYPE_PROCESSES_SECTION);
g_type_ensure (SYSPROF_TYPE_SAMPLES_SECTION);
g_type_ensure (SYSPROF_TYPE_STORAGE_SECTION);
g_type_ensure (SYSPROF_TYPE_SESSION);
g_type_ensure (SYSPROF_TYPE_SIDEBAR);
}

View File

@ -227,7 +227,7 @@
</object>
</child>
<child>
<object class="SysprofCountersSection">
<object class="SysprofStorageSection">
<property name="title" translatable="yes">Storage</property>
<property name="category">counters</property>
<property name="icon-name">storage-symbolic</property>

View File

@ -35,6 +35,7 @@
<file preprocess="xml-stripblanks">sysprof-recording-pad.ui</file>
<file preprocess="xml-stripblanks">sysprof-samples-section.ui</file>
<file preprocess="xml-stripblanks">sysprof-sidebar.ui</file>
<file preprocess="xml-stripblanks">sysprof-storage-section.ui</file>
<file preprocess="xml-stripblanks">sysprof-time-scrubber.ui</file>
<file preprocess="xml-stripblanks">sysprof-traceables-utility.ui</file>
<file preprocess="xml-stripblanks">sysprof-weighted-callgraph-view.ui</file>