mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-10 07:00:53 +00:00
*** empty log message ***
This commit is contained in:
@ -265,7 +265,7 @@ process_lookup_symbol (Process *process, gulong address)
|
|||||||
{
|
{
|
||||||
if (undefined.name)
|
if (undefined.name)
|
||||||
g_free (undefined.name);
|
g_free (undefined.name);
|
||||||
undefined.name = g_strdup_printf ("??? (%s)", process->cmdline);
|
undefined.name = g_strdup_printf ("??? %s", process->cmdline);
|
||||||
undefined.address = 0xBABE0001;
|
undefined.address = 0xBABE0001;
|
||||||
|
|
||||||
return &undefined;
|
return &undefined;
|
||||||
|
|||||||
174
profile.c
174
profile.c
@ -27,14 +27,14 @@ direct_hash_no_null (gconstpointer v)
|
|||||||
struct Node
|
struct Node
|
||||||
{
|
{
|
||||||
ProfileObject *object;
|
ProfileObject *object;
|
||||||
|
|
||||||
Node *siblings; /* siblings in the call tree */
|
Node *siblings; /* siblings in the call tree */
|
||||||
Node *children; /* children in the call tree */
|
Node *children; /* children in the call tree */
|
||||||
Node *parent; /* parent in call tree */
|
Node *parent; /* parent in call tree */
|
||||||
Node *next; /* nodes that correspond to same object are linked though
|
Node *next; /* nodes that correspond to same object are linked though
|
||||||
* this pointer
|
* this pointer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
guint total;
|
guint total;
|
||||||
guint self;
|
guint self;
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ struct Profile
|
|||||||
{
|
{
|
||||||
gint size;
|
gint size;
|
||||||
Node * call_tree;
|
Node * call_tree;
|
||||||
|
|
||||||
/* This table is really a cache. We can build it from the call_tree */
|
/* This table is really a cache. We can build it from the call_tree */
|
||||||
GHashTable * nodes_by_object;
|
GHashTable * nodes_by_object;
|
||||||
};
|
};
|
||||||
@ -79,14 +79,19 @@ insert (SaveContext *context, int id, gpointer pointer)
|
|||||||
static int
|
static int
|
||||||
get_id (SaveContext *context, gpointer pointer)
|
get_id (SaveContext *context, gpointer pointer)
|
||||||
{
|
{
|
||||||
int id = GPOINTER_TO_INT (g_hash_table_lookup (context->id_by_pointer, pointer));
|
int id;
|
||||||
|
|
||||||
|
if (!pointer)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
id = GPOINTER_TO_INT (g_hash_table_lookup (context->id_by_pointer, pointer));
|
||||||
|
|
||||||
if (!id)
|
if (!id)
|
||||||
{
|
{
|
||||||
id = ++context->last_id;
|
id = ++context->last_id;
|
||||||
insert (context, id, pointer);
|
insert (context, id, pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,25 +101,62 @@ serialize_object (gpointer key, gpointer value, gpointer data)
|
|||||||
SaveContext *context = data;
|
SaveContext *context = data;
|
||||||
ProfileObject *object = key;
|
ProfileObject *object = key;
|
||||||
|
|
||||||
g_string_append_printf (context->str, "<object id=%d name=%s total=%d self=%d/>\n",
|
g_string_append_printf (context->str, " <object id=%d name=\"%s\" total=%d self=%d/>\n",
|
||||||
get_id (context, object),
|
get_id (context, object),
|
||||||
object->name,
|
object->name,
|
||||||
object->total,
|
object->total,
|
||||||
object->self);
|
object->self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
serialize_call_tree (Node *node, SaveContext *context)
|
||||||
|
{
|
||||||
|
if (!node)
|
||||||
|
return;
|
||||||
|
|
||||||
|
g_string_append_printf (context->str,
|
||||||
|
" <node id=%d object=%d siblings=%d children=%d parent=%d next=%d total=%d self=%d>\n",
|
||||||
|
get_id (context, node),
|
||||||
|
get_id (context, node->object),
|
||||||
|
get_id (context, node->siblings),
|
||||||
|
get_id (context, node->children),
|
||||||
|
get_id (context, node->parent),
|
||||||
|
get_id (context, node->next),
|
||||||
|
node->total,
|
||||||
|
node->self);
|
||||||
|
|
||||||
|
serialize_call_tree (node->siblings, context);
|
||||||
|
serialize_call_tree (node->children, context);
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
profile_save (Profile *profile,
|
profile_save (Profile *profile,
|
||||||
const char *file_name,
|
const char *file_name,
|
||||||
GError **err)
|
GError **err)
|
||||||
{
|
{
|
||||||
GString *str = g_string_new ("");
|
SaveContext context;
|
||||||
|
|
||||||
g_string_append_printf (str, "<profile>\n");
|
context.str = g_string_new ("");
|
||||||
|
context.id_by_pointer = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
|
context.pointer_by_id = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
|
context.last_id = 0;
|
||||||
|
|
||||||
|
g_string_append_printf (context.str, "<profile>\n <objects>\n");
|
||||||
|
|
||||||
g_hash_table_foreach (profile->nodes_by_object, serialize_object, str);
|
g_hash_table_foreach (profile->nodes_by_object, serialize_object, &context);
|
||||||
g_string_append_printf (str, "</profile>\n");
|
|
||||||
/* FIXME */
|
g_string_append_printf (context.str, " </objects>\n <nodes>\n");
|
||||||
|
|
||||||
|
serialize_call_tree (profile->call_tree, &context);
|
||||||
|
|
||||||
|
g_string_append_printf (context.str, " </nodes>\n</profile>\n");
|
||||||
|
|
||||||
|
g_hash_table_destroy (context.id_by_pointer);
|
||||||
|
g_hash_table_destroy (context.pointer_by_id);
|
||||||
|
|
||||||
|
g_print (context.str->str);
|
||||||
|
|
||||||
|
g_string_free (context.str, TRUE);
|
||||||
|
|
||||||
/* Actually the way to fix this is probably to save StackStashes instead
|
/* Actually the way to fix this is probably to save StackStashes instead
|
||||||
* of profiles
|
* of profiles
|
||||||
@ -143,7 +185,7 @@ generate_key (Process *process, gulong address)
|
|||||||
if (address)
|
if (address)
|
||||||
{
|
{
|
||||||
const Symbol *symbol = process_lookup_symbol (process, address);
|
const Symbol *symbol = process_lookup_symbol (process, address);
|
||||||
|
|
||||||
return g_strdup_printf ("%p%s", (void *)symbol->address, symbol->name);
|
return g_strdup_printf ("%p%s", (void *)symbol->address, symbol->name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -159,7 +201,7 @@ generate_presentation_name (Process *process, gulong address)
|
|||||||
if (address)
|
if (address)
|
||||||
{
|
{
|
||||||
const Symbol *symbol = process_lookup_symbol (process, address);
|
const Symbol *symbol = process_lookup_symbol (process, address);
|
||||||
|
|
||||||
return g_strdup_printf ("%s", symbol->name);
|
return g_strdup_printf ("%s", symbol->name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -176,14 +218,14 @@ static void
|
|||||||
ensure_profile_node (GHashTable *profile_objects, Process *process, gulong address)
|
ensure_profile_node (GHashTable *profile_objects, Process *process, gulong address)
|
||||||
{
|
{
|
||||||
char *key = generate_key (process, address);
|
char *key = generate_key (process, address);
|
||||||
|
|
||||||
if (!g_hash_table_lookup (profile_objects, key))
|
if (!g_hash_table_lookup (profile_objects, key))
|
||||||
{
|
{
|
||||||
ProfileObject *object;
|
ProfileObject *object;
|
||||||
|
|
||||||
object = profile_object_new ();
|
object = profile_object_new ();
|
||||||
object->name = generate_presentation_name (process, address);
|
object->name = generate_presentation_name (process, address);
|
||||||
|
|
||||||
g_hash_table_insert (profile_objects, key, object);
|
g_hash_table_insert (profile_objects, key, object);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -217,13 +259,13 @@ generate_object_table (Process *process, GSList *trace, gint size, gpointer data
|
|||||||
GSList *list;
|
GSList *list;
|
||||||
|
|
||||||
ensure_profile_node (info->profile_objects, process, 0);
|
ensure_profile_node (info->profile_objects, process, 0);
|
||||||
|
|
||||||
for (list = trace; list != NULL; list = list->next)
|
for (list = trace; list != NULL; list = list->next)
|
||||||
{
|
{
|
||||||
update ();
|
update ();
|
||||||
ensure_profile_node (info->profile_objects, process, (gulong)list->data);
|
ensure_profile_node (info->profile_objects, process, (gulong)list->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
info->profile->size += size;
|
info->profile->size += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +291,7 @@ node_add_trace (Profile *profile, GHashTable *profile_objects, Node *node, Proce
|
|||||||
{
|
{
|
||||||
ProfileObject *object;
|
ProfileObject *object;
|
||||||
Node *match = NULL;
|
Node *match = NULL;
|
||||||
|
|
||||||
if (!trace)
|
if (!trace)
|
||||||
return node;
|
return node;
|
||||||
|
|
||||||
@ -259,25 +301,25 @@ node_add_trace (Profile *profile, GHashTable *profile_objects, Node *node, Proce
|
|||||||
if (match->object == object)
|
if (match->object == object)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!match)
|
if (!match)
|
||||||
{
|
{
|
||||||
match = node_new ();
|
match = node_new ();
|
||||||
match->object = object;
|
match->object = object;
|
||||||
match->siblings = node;
|
match->siblings = node;
|
||||||
node = match;
|
node = match;
|
||||||
|
|
||||||
if (g_hash_table_lookup (seen_objects, object))
|
if (g_hash_table_lookup (seen_objects, object))
|
||||||
match->toplevel = FALSE;
|
match->toplevel = FALSE;
|
||||||
else
|
else
|
||||||
match->toplevel = TRUE;
|
match->toplevel = TRUE;
|
||||||
|
|
||||||
match->next = g_hash_table_lookup (profile->nodes_by_object, object);
|
match->next = g_hash_table_lookup (profile->nodes_by_object, object);
|
||||||
g_hash_table_insert (profile->nodes_by_object, object, match);
|
g_hash_table_insert (profile->nodes_by_object, object, match);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_insert (seen_objects, object, GINT_TO_POINTER (1));
|
g_hash_table_insert (seen_objects, object, GINT_TO_POINTER (1));
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
g_print ("%s adds %d\n", match->object->name, size);
|
g_print ("%s adds %d\n", match->object->name, size);
|
||||||
#endif
|
#endif
|
||||||
@ -312,13 +354,13 @@ generate_call_tree (Process *process, GSList *trace, gint size, gpointer data)
|
|||||||
Node *match = NULL;
|
Node *match = NULL;
|
||||||
ProfileObject *proc = lookup_profile_object (info->profile_objects, process, 0);
|
ProfileObject *proc = lookup_profile_object (info->profile_objects, process, 0);
|
||||||
GHashTable *seen_objects;
|
GHashTable *seen_objects;
|
||||||
|
|
||||||
for (match = info->profile->call_tree; match; match = match->siblings)
|
for (match = info->profile->call_tree; match; match = match->siblings)
|
||||||
{
|
{
|
||||||
if (match->object == proc)
|
if (match->object == proc)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!match)
|
if (!match)
|
||||||
{
|
{
|
||||||
match = node_new ();
|
match = node_new ();
|
||||||
@ -327,17 +369,17 @@ generate_call_tree (Process *process, GSList *trace, gint size, gpointer data)
|
|||||||
info->profile->call_tree = match;
|
info->profile->call_tree = match;
|
||||||
match->toplevel = TRUE;
|
match->toplevel = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_hash_table_insert (info->profile->nodes_by_object, proc, match);
|
g_hash_table_insert (info->profile->nodes_by_object, proc, match);
|
||||||
|
|
||||||
match->total += size;
|
match->total += size;
|
||||||
if (!trace)
|
if (!trace)
|
||||||
match->self += size;
|
match->self += size;
|
||||||
|
|
||||||
seen_objects = g_hash_table_new (direct_hash_no_null, g_direct_equal);
|
seen_objects = g_hash_table_new (direct_hash_no_null, g_direct_equal);
|
||||||
|
|
||||||
g_hash_table_insert (seen_objects, proc, GINT_TO_POINTER (1));
|
g_hash_table_insert (seen_objects, proc, GINT_TO_POINTER (1));
|
||||||
|
|
||||||
update ();
|
update ();
|
||||||
match->children = node_add_trace (info->profile, info->profile_objects, match->children, process,
|
match->children = node_add_trace (info->profile, info->profile_objects, match->children, process,
|
||||||
trace, size, seen_objects);
|
trace, size, seen_objects);
|
||||||
@ -362,7 +404,7 @@ compute_object_total (gpointer key, gpointer value, gpointer data)
|
|||||||
{
|
{
|
||||||
Node *node;
|
Node *node;
|
||||||
ProfileObject *object = key;
|
ProfileObject *object = key;
|
||||||
|
|
||||||
for (node = value; node != NULL; node = node->next)
|
for (node = value; node != NULL; node = node->next)
|
||||||
{
|
{
|
||||||
object->self += node->self;
|
object->self += node->self;
|
||||||
@ -376,14 +418,14 @@ profile_new (StackStash *stash)
|
|||||||
{
|
{
|
||||||
Profile *profile = g_new (Profile, 1);
|
Profile *profile = g_new (Profile, 1);
|
||||||
Info info;
|
Info info;
|
||||||
|
|
||||||
profile->call_tree = NULL;
|
profile->call_tree = NULL;
|
||||||
|
|
||||||
profile->nodes_by_object =
|
profile->nodes_by_object =
|
||||||
g_hash_table_new (direct_hash_no_null, g_direct_equal);
|
g_hash_table_new (direct_hash_no_null, g_direct_equal);
|
||||||
|
|
||||||
profile->size = 0;
|
profile->size = 0;
|
||||||
|
|
||||||
info.profile = profile;
|
info.profile = profile;
|
||||||
info.profile_objects = g_hash_table_new_full (g_str_hash, g_str_equal,
|
info.profile_objects = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
g_free, NULL);
|
g_free, NULL);
|
||||||
@ -391,7 +433,7 @@ profile_new (StackStash *stash)
|
|||||||
stack_stash_foreach (stash, generate_object_table, &info);
|
stack_stash_foreach (stash, generate_object_table, &info);
|
||||||
stack_stash_foreach (stash, generate_call_tree, &info);
|
stack_stash_foreach (stash, generate_call_tree, &info);
|
||||||
link_parents (profile->call_tree, NULL);
|
link_parents (profile->call_tree, NULL);
|
||||||
|
|
||||||
g_hash_table_foreach (profile->nodes_by_object, compute_object_total, NULL);
|
g_hash_table_foreach (profile->nodes_by_object, compute_object_total, NULL);
|
||||||
|
|
||||||
g_hash_table_destroy (info.profile_objects);
|
g_hash_table_destroy (info.profile_objects);
|
||||||
@ -409,14 +451,14 @@ add_trace_to_tree (ProfileDescendant **tree, GList *trace, guint size)
|
|||||||
|
|
||||||
GHashTable *seen_objects =
|
GHashTable *seen_objects =
|
||||||
g_hash_table_new (direct_hash_no_null, g_direct_equal);
|
g_hash_table_new (direct_hash_no_null, g_direct_equal);
|
||||||
|
|
||||||
for (list = trace; list != NULL; list = list->next)
|
for (list = trace; list != NULL; list = list->next)
|
||||||
{
|
{
|
||||||
Node *node = list->data;
|
Node *node = list->data;
|
||||||
ProfileDescendant *match = NULL;
|
ProfileDescendant *match = NULL;
|
||||||
|
|
||||||
update();
|
update();
|
||||||
|
|
||||||
for (match = *tree; match != NULL; match = match->siblings)
|
for (match = *tree; match != NULL; match = match->siblings)
|
||||||
{
|
{
|
||||||
if (match->object == node->object)
|
if (match->object == node->object)
|
||||||
@ -520,7 +562,7 @@ node_list_leaves (Node *node, GList **leaves)
|
|||||||
|
|
||||||
if (node->self > 0)
|
if (node->self > 0)
|
||||||
*leaves = g_list_prepend (*leaves, node);
|
*leaves = g_list_prepend (*leaves, node);
|
||||||
|
|
||||||
for (n = node->children; n != NULL; n = n->siblings)
|
for (n = node->children; n != NULL; n = n->siblings)
|
||||||
node_list_leaves (n, leaves);
|
node_list_leaves (n, leaves);
|
||||||
}
|
}
|
||||||
@ -530,10 +572,10 @@ add_leaf_to_tree (ProfileDescendant **tree, Node *leaf, Node *top)
|
|||||||
{
|
{
|
||||||
GList *trace = NULL;
|
GList *trace = NULL;
|
||||||
Node *node;
|
Node *node;
|
||||||
|
|
||||||
for (node = leaf; node != top->parent; node = node->parent)
|
for (node = leaf; node != top->parent; node = node->parent)
|
||||||
trace = g_list_prepend (trace, node);
|
trace = g_list_prepend (trace, node);
|
||||||
|
|
||||||
add_trace_to_tree (tree, trace, leaf->self);
|
add_trace_to_tree (tree, trace, leaf->self);
|
||||||
|
|
||||||
g_list_free (trace);
|
g_list_free (trace);
|
||||||
@ -544,9 +586,9 @@ profile_create_descendants (Profile *profile, ProfileObject *object)
|
|||||||
{
|
{
|
||||||
ProfileDescendant *tree = NULL;
|
ProfileDescendant *tree = NULL;
|
||||||
Node *node;
|
Node *node;
|
||||||
|
|
||||||
node = g_hash_table_lookup (profile->nodes_by_object, object);
|
node = g_hash_table_lookup (profile->nodes_by_object, object);
|
||||||
|
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
update();
|
update();
|
||||||
@ -554,17 +596,17 @@ profile_create_descendants (Profile *profile, ProfileObject *object)
|
|||||||
{
|
{
|
||||||
GList *leaves = NULL;
|
GList *leaves = NULL;
|
||||||
GList *list;
|
GList *list;
|
||||||
|
|
||||||
node_list_leaves (node, &leaves);
|
node_list_leaves (node, &leaves);
|
||||||
|
|
||||||
for (list = leaves; list != NULL; list = list->next)
|
for (list = leaves; list != NULL; list = list->next)
|
||||||
add_leaf_to_tree (&tree, list->data, node);
|
add_leaf_to_tree (&tree, list->data, node);
|
||||||
|
|
||||||
g_list_free (leaves);
|
g_list_free (leaves);
|
||||||
}
|
}
|
||||||
node = node->next;
|
node = node->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -587,13 +629,13 @@ profile_list_callers (Profile *profile,
|
|||||||
GHashTable *callers_by_object;
|
GHashTable *callers_by_object;
|
||||||
GHashTable *seen_callers;
|
GHashTable *seen_callers;
|
||||||
ProfileCaller *result = NULL;
|
ProfileCaller *result = NULL;
|
||||||
|
|
||||||
callers_by_object =
|
callers_by_object =
|
||||||
g_hash_table_new (g_direct_hash, g_direct_equal);
|
g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
seen_callers = g_hash_table_new (g_direct_hash, g_direct_equal);
|
seen_callers = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||||
|
|
||||||
callee_node = g_hash_table_lookup (profile->nodes_by_object, callee);
|
callee_node = g_hash_table_lookup (profile->nodes_by_object, callee);
|
||||||
|
|
||||||
for (node = callee_node; node; node = node->next)
|
for (node = callee_node; node; node = node->next)
|
||||||
{
|
{
|
||||||
ProfileObject *object;
|
ProfileObject *object;
|
||||||
@ -601,18 +643,18 @@ profile_list_callers (Profile *profile,
|
|||||||
object = node->parent->object;
|
object = node->parent->object;
|
||||||
else
|
else
|
||||||
object = NULL;
|
object = NULL;
|
||||||
|
|
||||||
if (!g_hash_table_lookup (callers_by_object, object))
|
if (!g_hash_table_lookup (callers_by_object, object))
|
||||||
{
|
{
|
||||||
ProfileCaller *caller = profile_caller_new ();
|
ProfileCaller *caller = profile_caller_new ();
|
||||||
caller->object = object;
|
caller->object = object;
|
||||||
g_hash_table_insert (callers_by_object, object, caller);
|
g_hash_table_insert (callers_by_object, object, caller);
|
||||||
|
|
||||||
caller->next = result;
|
caller->next = result;
|
||||||
result = caller;
|
result = caller;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (node = callee_node; node != NULL; node = node->next)
|
for (node = callee_node; node != NULL; node = node->next)
|
||||||
{
|
{
|
||||||
Node *top_caller;
|
Node *top_caller;
|
||||||
@ -620,14 +662,14 @@ profile_list_callers (Profile *profile,
|
|||||||
Node *n;
|
Node *n;
|
||||||
ProfileCaller *caller;
|
ProfileCaller *caller;
|
||||||
ProfileObject *object;
|
ProfileObject *object;
|
||||||
|
|
||||||
if (node->parent)
|
if (node->parent)
|
||||||
object = node->parent->object;
|
object = node->parent->object;
|
||||||
else
|
else
|
||||||
object = NULL;
|
object = NULL;
|
||||||
|
|
||||||
caller = g_hash_table_lookup (callers_by_object, object);
|
caller = g_hash_table_lookup (callers_by_object, object);
|
||||||
|
|
||||||
/* find topmost node/parent pair identical to this node/parent */
|
/* find topmost node/parent pair identical to this node/parent */
|
||||||
top_caller = node->parent;
|
top_caller = node->parent;
|
||||||
top_callee = node;
|
top_callee = node;
|
||||||
@ -664,7 +706,7 @@ node_free (Node *node)
|
|||||||
{
|
{
|
||||||
if (!node)
|
if (!node)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
node_free (node->siblings);
|
node_free (node->siblings);
|
||||||
node_free (node->children);
|
node_free (node->children);
|
||||||
g_free (node);
|
g_free (node);
|
||||||
@ -680,7 +722,7 @@ void
|
|||||||
profile_free (Profile *profile)
|
profile_free (Profile *profile)
|
||||||
{
|
{
|
||||||
g_hash_table_foreach (profile->nodes_by_object, free_object, NULL);
|
g_hash_table_foreach (profile->nodes_by_object, free_object, NULL);
|
||||||
|
|
||||||
node_free (profile->call_tree);
|
node_free (profile->call_tree);
|
||||||
|
|
||||||
g_hash_table_destroy (profile->nodes_by_object);
|
g_hash_table_destroy (profile->nodes_by_object);
|
||||||
@ -693,10 +735,10 @@ profile_descendant_free (ProfileDescendant *descendant)
|
|||||||
{
|
{
|
||||||
if (!descendant)
|
if (!descendant)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
profile_descendant_free (descendant->siblings);
|
profile_descendant_free (descendant->siblings);
|
||||||
profile_descendant_free (descendant->children);
|
profile_descendant_free (descendant->children);
|
||||||
|
|
||||||
g_free (descendant);
|
g_free (descendant);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -705,7 +747,7 @@ profile_caller_free (ProfileCaller *caller)
|
|||||||
{
|
{
|
||||||
if (!caller)
|
if (!caller)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
profile_caller_free (caller->next);
|
profile_caller_free (caller->next);
|
||||||
g_free (caller);
|
g_free (caller);
|
||||||
}
|
}
|
||||||
@ -715,7 +757,7 @@ build_object_list (gpointer key, gpointer value, gpointer data)
|
|||||||
{
|
{
|
||||||
ProfileObject *object = key;
|
ProfileObject *object = key;
|
||||||
GList **objects = data;
|
GList **objects = data;
|
||||||
|
|
||||||
*objects = g_list_prepend (*objects, object);
|
*objects = g_list_prepend (*objects, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -723,9 +765,9 @@ GList *
|
|||||||
profile_get_objects (Profile *profile)
|
profile_get_objects (Profile *profile)
|
||||||
{
|
{
|
||||||
GList *objects = NULL;
|
GList *objects = NULL;
|
||||||
|
|
||||||
g_hash_table_foreach (profile->nodes_by_object, build_object_list, &objects);
|
g_hash_table_foreach (profile->nodes_by_object, build_object_list, &objects);
|
||||||
|
|
||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
36
sysprof.c
36
sysprof.c
@ -331,23 +331,14 @@ fill_main_list (Application *app)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_profile_toggled (gpointer widget, gpointer data)
|
ensure_profile (Application *app)
|
||||||
{
|
{
|
||||||
Application *app = data;
|
if (app->profile)
|
||||||
|
|
||||||
if (app->generating_profile || !gtk_toggle_tool_button_get_active (widget))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (app->profile)
|
|
||||||
profile_free (app->profile);
|
|
||||||
|
|
||||||
/* take care of reentrancy */
|
/* take care of reentrancy */
|
||||||
app->generating_profile = TRUE;
|
|
||||||
|
|
||||||
app->profile = profile_new (app->stash);
|
app->profile = profile_new (app->stash);
|
||||||
|
|
||||||
app->generating_profile = FALSE;
|
|
||||||
|
|
||||||
fill_main_list (app);
|
fill_main_list (app);
|
||||||
|
|
||||||
app->state = DISPLAYING;
|
app->state = DISPLAYING;
|
||||||
@ -361,6 +352,23 @@ on_profile_toggled (gpointer widget, gpointer data)
|
|||||||
update_sensitivity (app);
|
update_sensitivity (app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_profile_toggled (gpointer widget, gpointer data)
|
||||||
|
{
|
||||||
|
Application *app = data;
|
||||||
|
|
||||||
|
if (gtk_toggle_tool_button_get_active (widget))
|
||||||
|
{
|
||||||
|
if (app->profile)
|
||||||
|
{
|
||||||
|
profile_free (app->profile);
|
||||||
|
app->profile = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_profile (app);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sorry (GtkWidget *parent_window,
|
sorry (GtkWidget *parent_window,
|
||||||
const gchar *format,
|
const gchar *format,
|
||||||
@ -409,8 +417,14 @@ static void
|
|||||||
on_save_as_clicked (gpointer widget, gpointer data)
|
on_save_as_clicked (gpointer widget, gpointer data)
|
||||||
{
|
{
|
||||||
Application *app = data;
|
Application *app = data;
|
||||||
|
|
||||||
|
ensure_profile (app);
|
||||||
|
|
||||||
|
profile_save (app->profile, NULL, NULL);
|
||||||
|
|
||||||
|
#if 0
|
||||||
sorry (NULL, "Saving profiles is not yet implemented.");
|
sorry (NULL, "Saving profiles is not yet implemented.");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (app)
|
if (app)
|
||||||
;
|
;
|
||||||
|
|||||||
Reference in New Issue
Block a user