|
Packit Service |
2781ba |
/* This file is part of GEGL
|
|
Packit Service |
2781ba |
*
|
|
Packit Service |
2781ba |
* GEGL is free software; you can redistribute it and/or
|
|
Packit Service |
2781ba |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit Service |
2781ba |
* License as published by the Free Software Foundation; either
|
|
Packit Service |
2781ba |
* version 3 of the License, or (at your option) any later version.
|
|
Packit Service |
2781ba |
*
|
|
Packit Service |
2781ba |
* GEGL is distributed in the hope that it will be useful,
|
|
Packit Service |
2781ba |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
2781ba |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
2781ba |
* Lesser General Public License for more details.
|
|
Packit Service |
2781ba |
*
|
|
Packit Service |
2781ba |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit Service |
2781ba |
* License along with GEGL; if not, see <http://www.gnu.org/licenses/>.
|
|
Packit Service |
2781ba |
*
|
|
Packit Service |
2781ba |
* Copyright 2006 Øyvind Kolås
|
|
Packit Service |
2781ba |
*/
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#include "config.h"
|
|
Packit Service |
2781ba |
#include <glib.h>
|
|
Packit Service |
2781ba |
#include <string.h>
|
|
Packit Service |
2781ba |
#include "gegl-instrument.h"
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
long babl_ticks (void);
|
|
Packit Service |
2781ba |
long gegl_ticks (void)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
return babl_ticks ();
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
typedef struct _Timing Timing;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
struct _Timing
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
gchar *name;
|
|
Packit Service |
2781ba |
long usecs;
|
|
Packit Service |
2781ba |
Timing *parent;
|
|
Packit Service |
2781ba |
Timing *children;
|
|
Packit Service |
2781ba |
Timing *next;
|
|
Packit Service |
2781ba |
};
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static Timing *root = NULL;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static Timing *iter_next (Timing *iter)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
if (iter->children)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
iter = iter->children;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else if (iter->next)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
iter = iter->next;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
while (iter && !iter->next)
|
|
Packit Service |
2781ba |
iter = iter->parent;
|
|
Packit Service |
2781ba |
if (iter && iter->next)
|
|
Packit Service |
2781ba |
iter = iter->next;
|
|
Packit Service |
2781ba |
else
|
|
Packit Service |
2781ba |
return NULL;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
return iter;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static gint timing_depth (Timing *timing)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
Timing *iter = timing;
|
|
Packit Service |
2781ba |
gint ret = 0;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
while (iter &&
|
|
Packit Service |
2781ba |
iter->parent)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
ret++;
|
|
Packit Service |
2781ba |
iter = iter->parent;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return ret;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static Timing *timing_find (Timing *root,
|
|
Packit Service |
2781ba |
const gchar *name)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
Timing *iter = root;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (!iter)
|
|
Packit Service |
2781ba |
return NULL;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
while (iter)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
if (!strcmp (iter->name, name))
|
|
Packit Service |
2781ba |
return iter;
|
|
Packit Service |
2781ba |
if (timing_depth (iter_next (iter)) <= timing_depth (root))
|
|
Packit Service |
2781ba |
return NULL;
|
|
Packit Service |
2781ba |
iter = iter_next (iter);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
return NULL;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
void
|
|
Packit Service |
2781ba |
gegl_instrument (const gchar *parent_name,
|
|
Packit Service |
2781ba |
const gchar *name,
|
|
Packit Service |
2781ba |
long usecs)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
Timing *iter;
|
|
Packit Service |
2781ba |
Timing *parent;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (root == NULL)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
root = g_slice_new0 (Timing);
|
|
Packit Service |
2781ba |
root->name = g_strdup (parent_name);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
parent = timing_find (root, parent_name);
|
|
Packit Service |
2781ba |
if (!parent)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
gegl_instrument (root->name, parent_name, 0);
|
|
Packit Service |
2781ba |
parent = timing_find (root, parent_name);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
g_assert (parent);
|
|
Packit Service |
2781ba |
iter = timing_find (parent, name);
|
|
Packit Service |
2781ba |
if (!iter)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
iter = g_slice_new0 (Timing);
|
|
Packit Service |
2781ba |
iter->name = g_strdup (name);
|
|
Packit Service |
2781ba |
iter->parent = parent;
|
|
Packit Service |
2781ba |
iter->next = parent->children;
|
|
Packit Service |
2781ba |
parent->children = iter;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
iter->usecs += usecs;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static glong timing_child_sum (Timing *timing)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
Timing *iter = timing->children;
|
|
Packit Service |
2781ba |
glong sum = 0;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
while (iter)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
sum += iter->usecs;
|
|
Packit Service |
2781ba |
iter = iter->next;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
return sum;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static glong timing_other (Timing *timing)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
if (timing->children)
|
|
Packit Service |
2781ba |
return timing->usecs - timing_child_sum (timing);
|
|
Packit Service |
2781ba |
return 0;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static float seconds (glong usecs)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
return usecs / 1000000.0;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static float normalized (glong usecs)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
return 1.0 * usecs / root->usecs;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#include <string.h>
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static GString *
|
|
Packit Service |
2781ba |
tab_to (GString *string, gint position)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
gchar *p;
|
|
Packit Service |
2781ba |
gint curcount = 0;
|
|
Packit Service |
2781ba |
gint i;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
p = strrchr (string->str, '\n');
|
|
Packit Service |
2781ba |
if (!p)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
p = string->str;
|
|
Packit Service |
2781ba |
curcount++;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
while (p && *p != '\0')
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
curcount++;
|
|
Packit Service |
2781ba |
p++;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (curcount > position && position != 0)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
g_warning ("%s tab overflow %i>%i", G_STRLOC, curcount, position);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
for (i = 0; i <= position - curcount; i++)
|
|
Packit Service |
2781ba |
string = g_string_append (string, " ");
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
return string;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static gchar *eight[] = {
|
|
Packit Service |
2781ba |
" ",
|
|
Packit Service |
2781ba |
"▏",
|
|
Packit Service |
2781ba |
"▍",
|
|
Packit Service |
2781ba |
"▌",
|
|
Packit Service |
2781ba |
"▋",
|
|
Packit Service |
2781ba |
"▊",
|
|
Packit Service |
2781ba |
"▉",
|
|
Packit Service |
2781ba |
"█"
|
|
Packit Service |
2781ba |
};
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static GString *
|
|
Packit Service |
2781ba |
bar (GString *string, gint width, gfloat value)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
gboolean utf8 = TRUE;
|
|
Packit Service |
2781ba |
gint i;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (value < 0)
|
|
Packit Service |
2781ba |
return string;
|
|
Packit Service |
2781ba |
if (utf8)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
gint blocks = width * 8 * value;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
for (i = 0; i < blocks / 8; i++)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
string = g_string_append (string, "█");
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
string = g_string_append (string, eight[blocks % 8]);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
for (i = 0; i < width; i++)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
if (width * value > i)
|
|
Packit Service |
2781ba |
string = g_string_append (string, "X");
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
return string;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
#define INDENT_SPACES 2
|
|
Packit Service |
2781ba |
#define SECONDS_COL 29
|
|
Packit Service |
2781ba |
#define BAR_COL 36
|
|
Packit Service |
2781ba |
#define BAR_WIDTH (78 - BAR_COL)
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
static void
|
|
Packit Service |
2781ba |
sort_children (Timing *parent)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
Timing *iter;
|
|
Packit Service |
2781ba |
Timing *prev;
|
|
Packit Service |
2781ba |
gboolean changed = FALSE;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
do
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
iter = parent->children;
|
|
Packit Service |
2781ba |
changed = FALSE;
|
|
Packit Service |
2781ba |
prev = NULL;
|
|
Packit Service |
2781ba |
while (iter && iter->next)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
Timing *next = iter->next;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (next->usecs > iter->usecs)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
changed = TRUE;
|
|
Packit Service |
2781ba |
if (prev)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
prev->next = next;
|
|
Packit Service |
2781ba |
iter->next = next->next;
|
|
Packit Service |
2781ba |
next->next = iter;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
else
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
iter->next = next->next;
|
|
Packit Service |
2781ba |
next->next = iter;
|
|
Packit Service |
2781ba |
parent->children = next;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
prev = iter;
|
|
Packit Service |
2781ba |
iter = iter->next;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
} while (changed);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
iter = parent->children;
|
|
Packit Service |
2781ba |
while (iter && iter->next)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
sort_children (iter);
|
|
Packit Service |
2781ba |
iter = iter->next;
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
gchar *
|
|
Packit Service |
2781ba |
gegl_instrument_utf8 (void)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
GString *s = g_string_new ("");
|
|
Packit Service |
2781ba |
gchar *ret;
|
|
Packit Service |
2781ba |
Timing *iter = root;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
sort_children (root);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
while (iter)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
gchar *buf;
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (!strcmp (iter->name, root->name))
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
buf = g_strdup_printf ("Total time: %.3fs\n", seconds (iter->usecs));
|
|
Packit Service |
2781ba |
s = g_string_append (s, buf);
|
|
Packit Service |
2781ba |
g_free (buf);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
s = tab_to (s, timing_depth (iter) * INDENT_SPACES);
|
|
Packit Service |
2781ba |
s = g_string_append (s, iter->name);
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
s = tab_to (s, SECONDS_COL);
|
|
Packit Service |
2781ba |
buf = g_strdup_printf ("%5.1f%%", iter->parent ? 100.0 * iter->usecs / iter->parent->usecs : 100.0);
|
|
Packit Service |
2781ba |
s = g_string_append (s, buf);
|
|
Packit Service |
2781ba |
g_free (buf);
|
|
Packit Service |
2781ba |
s = tab_to (s, BAR_COL);
|
|
Packit Service |
2781ba |
s = bar (s, BAR_WIDTH, normalized (iter->usecs));
|
|
Packit Service |
2781ba |
s = g_string_append (s, "\n");
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
if (timing_depth (iter_next (iter)) < timing_depth (iter))
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
if (timing_other (iter->parent) > 0)
|
|
Packit Service |
2781ba |
{
|
|
Packit Service |
2781ba |
s = tab_to (s, timing_depth (iter) * INDENT_SPACES);
|
|
Packit Service |
2781ba |
s = g_string_append (s, "other");
|
|
Packit Service |
2781ba |
s = tab_to (s, SECONDS_COL);
|
|
Packit Service |
2781ba |
buf = g_strdup_printf ("%5.1f%%", 100 * normalized (timing_other (iter->parent)));
|
|
Packit Service |
2781ba |
s = g_string_append (s, buf);
|
|
Packit Service |
2781ba |
g_free (buf);
|
|
Packit Service |
2781ba |
s = tab_to (s, BAR_COL);
|
|
Packit Service |
2781ba |
s = bar (s, BAR_WIDTH, normalized (timing_other (iter->parent)));
|
|
Packit Service |
2781ba |
s = g_string_append (s, "\n");
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
s = g_string_append (s, "\n");
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
iter = iter_next (iter);
|
|
Packit Service |
2781ba |
}
|
|
Packit Service |
2781ba |
|
|
Packit Service |
2781ba |
ret = g_strdup (s->str);
|
|
Packit Service |
2781ba |
g_string_free (s, TRUE);
|
|
Packit Service |
2781ba |
return ret;
|
|
Packit Service |
2781ba |
}
|