mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
Experiment with a file-format-description format.
Wed Mar 2 23:39:50 2005 Soeren Sandmann <sandmann@redhat.com> * profile.[ch], sfile.[ch]: Experiment with a file-format-description format. * sysprof.c: Add commented out code using /proc/ based timeout.
This commit is contained in:
committed by
Søren Sandmann Pedersen
parent
5dec3764c1
commit
de4b3c076d
397
profile.c
397
profile.c
@ -6,7 +6,7 @@
|
||||
#include "process.h"
|
||||
#include "stackstash.h"
|
||||
#include "profile.h"
|
||||
|
||||
#include "sfile.h"
|
||||
|
||||
typedef struct Node Node;
|
||||
|
||||
@ -52,14 +52,118 @@ struct Profile
|
||||
GHashTable * nodes_by_object;
|
||||
};
|
||||
|
||||
typedef struct SaveContext SaveContext;
|
||||
struct SaveContext
|
||||
static SFormat *
|
||||
create_format (void)
|
||||
{
|
||||
GString *str;
|
||||
GHashTable *id_by_pointer;
|
||||
GHashTable *pointer_by_id;
|
||||
int last_id;
|
||||
};
|
||||
#if 0
|
||||
SType object_type = 0;
|
||||
SType node_type = 0;
|
||||
|
||||
return sformat_new (
|
||||
sformat_new_record (
|
||||
"profile",
|
||||
sformat_new_integer ("size", NULL),
|
||||
sformat_new_list (
|
||||
"objects", NULL,
|
||||
sformat_new_record (
|
||||
"object", &object_type,
|
||||
sformat_new_string ("name", NULL),
|
||||
sformat_new_integer ("total", NULL),
|
||||
sformat_new_integer ("self", NULL),
|
||||
NULL)),
|
||||
sformat_new_list (
|
||||
"nodes", NULL,
|
||||
sformat_new_record (
|
||||
"node", &node_type,
|
||||
sformat_new_pointer ("object", &object_type),
|
||||
sformat_new_pointer ("siblings", &node_type),
|
||||
sformat_new_pointer ("children", &node_type),
|
||||
sformat_new_pointer ("parent", &node_type),
|
||||
sformat_new_pointer ("next", &node_type),
|
||||
NULL)),
|
||||
NULL));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
add_object (gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
SFileOutput *output = data;
|
||||
ProfileObject *object = key;
|
||||
|
||||
sfile_begin_add_record (output, "object");
|
||||
|
||||
sfile_add_string (output, "name", object->name);
|
||||
sfile_add_integer (output, "total", object->total);
|
||||
sfile_add_integer (output, "self", object->self);
|
||||
|
||||
sfile_end_add (output, "object", object);
|
||||
}
|
||||
|
||||
static void
|
||||
serialize_call_tree (Node *node, SFileOutput *output)
|
||||
{
|
||||
sfile_begin_add_record (output, "node");
|
||||
sfile_add_pointer (output, "object", node->object);
|
||||
sfile_add_pointer (output, "siblings", node->siblings);
|
||||
sfile_add_pointer (output, "children", node->children);
|
||||
sfile_add_pointer (output, "parent", node->parent);
|
||||
sfile_add_pointer (output, "next", node->next);
|
||||
sfile_end_add (output, "node", node);
|
||||
|
||||
serialize_call_tree (node->siblings, output);
|
||||
serialize_call_tree (node->children, output);
|
||||
}
|
||||
|
||||
gboolean
|
||||
profile_save (Profile *profile,
|
||||
const char *file_name,
|
||||
GError **err)
|
||||
{
|
||||
gboolean result;
|
||||
|
||||
SFormat *format = create_format ();
|
||||
#if 0
|
||||
SFileOutput *output = sfile_output_new (format);
|
||||
sfile_begin_add_record (output, "profile");
|
||||
|
||||
sfile_add_integer (output, "size", profile->size);
|
||||
|
||||
sfile_begin_add_list (output, "objects");
|
||||
g_hash_table_foreach (profile->nodes_by_object, add_object, output);
|
||||
sfile_end_add (output, "objects", NULL);
|
||||
|
||||
sfile_begin_add_list (output, "nodes");
|
||||
serialize_call_tree (profile->call_tree, output);
|
||||
sfile_end_add (output, "nodes", NULL);
|
||||
|
||||
sfile_end_add (output, "profile", NULL);
|
||||
|
||||
result = sfile_output_save (output, file_name, err);
|
||||
|
||||
sformat_free (format);
|
||||
sfile_output_free (output);
|
||||
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
Profile *
|
||||
profile_load (const char *filename, GError **err)
|
||||
{
|
||||
SFormat *format = create_format ();
|
||||
SFileInput *input;
|
||||
|
||||
input = sfile_load (filename, format, err);
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
sformat_free (format);
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
static ProfileObject *
|
||||
profile_object_new (void)
|
||||
@ -71,283 +175,6 @@ profile_object_new (void)
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void
|
||||
insert (SaveContext *context, int id, gpointer pointer)
|
||||
{
|
||||
g_hash_table_insert (context->id_by_pointer, pointer, GINT_TO_POINTER (id));
|
||||
g_hash_table_insert (context->pointer_by_id, GINT_TO_POINTER (id), pointer);
|
||||
}
|
||||
|
||||
static int
|
||||
get_id (SaveContext *context, gpointer pointer)
|
||||
{
|
||||
int id;
|
||||
|
||||
if (!pointer)
|
||||
return 0;
|
||||
|
||||
id = GPOINTER_TO_INT (g_hash_table_lookup (context->id_by_pointer, pointer));
|
||||
|
||||
if (!id)
|
||||
{
|
||||
id = ++context->last_id;
|
||||
insert (context, id, pointer);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
static void
|
||||
serialize_object (gpointer key, gpointer value, gpointer data)
|
||||
{
|
||||
SaveContext *context = data;
|
||||
ProfileObject *object = key;
|
||||
|
||||
g_string_append_printf (context->str, " <object id=\"%d\" name=\"%s\" total=\"%d\" self=\"%d\"/>\n",
|
||||
get_id (context, object),
|
||||
object->name,
|
||||
object->total,
|
||||
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\" toplevel=\"%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,
|
||||
node->toplevel);
|
||||
|
||||
serialize_call_tree (node->siblings, context);
|
||||
serialize_call_tree (node->children, context);
|
||||
}
|
||||
|
||||
gboolean
|
||||
profile_save (Profile *profile,
|
||||
const char *file_name)
|
||||
{
|
||||
SaveContext context;
|
||||
|
||||
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, &context);
|
||||
|
||||
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);
|
||||
|
||||
/* FIXME - write it to disk, not screen */
|
||||
|
||||
g_print (context.str->str);
|
||||
|
||||
g_string_free (context.str, TRUE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct LoadContext LoadContext;
|
||||
struct LoadContext
|
||||
{
|
||||
GHashTable *objects_by_id;
|
||||
GHashTable *nodes_by_id;
|
||||
|
||||
};
|
||||
|
||||
static int
|
||||
get_number (const char *input_name,
|
||||
const char *target_name,
|
||||
const char *value)
|
||||
{
|
||||
if (strcmp (input_name, target_name) == 0)
|
||||
{
|
||||
char *end;
|
||||
int r = strtol (value, &end, 10);
|
||||
if (*end == '\0')
|
||||
return r;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static Node *
|
||||
create_node (const char **names,
|
||||
const char **values,
|
||||
int *id)
|
||||
{
|
||||
int i;
|
||||
|
||||
int object = -1;
|
||||
int siblings = -1;
|
||||
int children = -1;
|
||||
int parent = -1;
|
||||
int next = -1;
|
||||
int total = -1;
|
||||
int self = -1;
|
||||
|
||||
Node *node = node_new ();
|
||||
|
||||
for (i = 0; names[i] != NULL; ++i)
|
||||
{
|
||||
*id = get_number (names[i], "id", values[i]);
|
||||
node->object = GINT_TO_POINTER (get_number (names[i], "object", values[i]));
|
||||
node->siblings = GINT_TO_POITNER (get_number (names[i], "siblings", values[i]));
|
||||
node->children = GINT_TO_POINTER (get_number (names[i], "children", values[i]));
|
||||
node->parent = GINT_TO_POINTER (get_number (names[i], "parent", values[i]));
|
||||
node->next = GINT_TO_POINTER (get_number (names[i], "next", values[i]));
|
||||
node->total = get_number (names[i], "total", values[i]);
|
||||
node->self = get_number (names[i], "self", values[i]);
|
||||
}
|
||||
|
||||
if (id == -1 || object == -1 || siblings == -1 ||
|
||||
children == -1 || parent == -1 || next == -1 ||
|
||||
total == -1 || self == -1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node->object = GINT_TO_POINTER (object);
|
||||
node->siblings = GINT_TO_POINTER (siblings);
|
||||
|
||||
|
||||
i = 0;
|
||||
const char *name = attribute_names[i];
|
||||
const char *value = attribute_values[i];
|
||||
|
||||
if (strcmp (name, "id") == 0)
|
||||
{
|
||||
}
|
||||
else if (strcmp (name, "sibling") == 0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ProfileObject *
|
||||
create_object (const char **attribute_names, const char **attribute_values, int *id, GError **err)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
while (attribute_names[i])
|
||||
{
|
||||
const char *name = attribute_names[i];
|
||||
const char *value = attribute_values[i];
|
||||
|
||||
|
||||
|
||||
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_start_element (GMarkupParseContext *context,
|
||||
const char *element_name,
|
||||
const char **attribute_names,
|
||||
const char **attribute_values,
|
||||
gpointer user_data,
|
||||
GError **err)
|
||||
{
|
||||
int id;
|
||||
LoadContext *lc = user_data;
|
||||
|
||||
if (strcmp (element_name, "object") == 0)
|
||||
{
|
||||
ProfileObject *object = create_object (attribute_names, attribute_values, &id, err);
|
||||
|
||||
if (object)
|
||||
g_hash_table_insert (lc->objects_by_id, GINT_TO_POINTER (id), object);
|
||||
}
|
||||
else if (strcmp (element_name, "node") == 0)
|
||||
{
|
||||
Node *node = create_node (attribute_names, attribute_values, &id, err);
|
||||
|
||||
if (node)
|
||||
g_hash_table_insert (lc->nodes_by_id, GINT_TO_POINTER (id), node);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ignore anything but object and node */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
parse_end_element (GMarkupParseContext *context,
|
||||
const char *element_name,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
parse_error (GMarkupParseContext *context,
|
||||
GError **error,
|
||||
gpointer user_data)
|
||||
{
|
||||
}
|
||||
|
||||
Profile *
|
||||
profile_load (const char *filename,
|
||||
GError **err)
|
||||
{
|
||||
char *input = NULL;
|
||||
Profile *result = NULL;
|
||||
|
||||
GMarkupParser parser = {
|
||||
parse_start_element, parse_end_element, NULL, NULL, NULL,
|
||||
};
|
||||
|
||||
LoadContext load_context;
|
||||
GMarkupParseContext *parse_context;
|
||||
|
||||
if (!g_file_get_contents (filename, &input, NULL, err))
|
||||
return NULL;
|
||||
|
||||
parse_context = g_markup_parse_context_new (&parser, 0, NULL, NULL);
|
||||
|
||||
if (!g_markup_parse_context_parse (parse_context, input, -1, err))
|
||||
goto out;
|
||||
|
||||
if (!g_markup_parse_context_end_parse (parse_context, err))
|
||||
goto out;
|
||||
|
||||
g_markup_parse_context_free (parse_context);
|
||||
|
||||
out:
|
||||
g_free (input);
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
profile_object_free (ProfileObject *obj)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user