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:
Soeren Sandmann
2005-03-03 04:44:28 +00:00
committed by Søren Sandmann Pedersen
parent 5dec3764c1
commit de4b3c076d
8 changed files with 390 additions and 488 deletions

397
profile.c
View File

@ -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)
{