From f7e888e574b84b5f30586b18a5d01420eea960b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Sandmann=20Pedersen?= Date: Sat, 1 Oct 2005 05:23:58 +0000 Subject: [PATCH] Revert accidental commit of stackstash reorganisation --- ChangeLog | 4 --- Makefile.am | 4 --- TODO | 97 +++++++++++++++++++++----------------------------- profile.c | 10 ++---- stackstash.c | 84 +++++++++++++++++++++++++++++++------------ stackstash.h | 4 ++- sysprof-text.c | 6 ++-- sysprof.c | 22 ++++++++++-- 8 files changed, 131 insertions(+), 100 deletions(-) diff --git a/ChangeLog b/ChangeLog index e8670365..e54759ca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,3 @@ -Sat Oct 1 01:21:57 2005 Soeren Sandmann - - * TODO: Update - Wed Sep 28 12:08:32 2005 Søren Sandmann * sysprof-text.c: Add my name to the copyright statement diff --git a/Makefile.am b/Makefile.am index fe14ae2a..d477a8e0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -15,8 +15,6 @@ sysprof_SOURCES = \ sfile.c \ stackstash.h \ stackstash.c \ - helper.c \ - helper.h \ module/sysprof-module.h \ sysprof.c \ treeviewutils.h \ @@ -35,8 +33,6 @@ sysprof_text_SOURCES = \ sfile.c \ stackstash.h \ stackstash.c \ - helper.c \ - helper.h \ module/sysprof-module.h \ signal-handler.h \ signal-handler.c \ diff --git a/TODO b/TODO index 879bc903..e350673a 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,35 @@ +Before 1.0: + + - Update version numbers in source + + - Make tarball + + - Check that tarball works + + - cvs commit + + - cvs tag sysprof-1-0 + + - Update website + + - Announce on Freshmeat + + - Announce on gnome-announce + - Announce on kernel list. + + - Announce on Gnomefiles + + - Announce on news.gnome.org + - Send to slashdot/developers + - Announce on devtools list (?) + + - Announce on Advogato + link to archive + Before 1.0.1: * See if we can reproduce the problem where libraries didn't get correctly reloaded after new versions were installed. - This is just the (deleted) problem. * Build system - Find out what distributions it actually works on @@ -16,6 +43,10 @@ Before 1.0.1: Before 1.2: +* The handling of the global variable in signal-handler.[ch] needs to be + atomic - right now it isn't. The issue is what happens if a handled signal + arrives while we are manipulating the list? + * Figure out how to make sfile.[ch] use less memory. - In general clean sfile.[ch] up a little: - split out dfa in its own generic class @@ -174,35 +205,23 @@ http://www.linuxbase.org/spec/booksets/LSB-Embedded/LSB-Embedded/ehframe.html - Reorganise stackstash and profile - stackstash should just take traces of addresses without knowing - anything about what those addresses mean. + anything about what those addresses mean - stacktraces should then begin with a process - - stackstash should be extended so that the "create_descendant" - and "create_ancestor" code in profile.c can use it directly. - At that point, get rid of the profile tree, and rename - profile.c to analyze.c. - - - the profile tree will then just be a stackstash where the - addresses are presentation strings instead. - - - Doing a profile will then amount to converting the raw stash - to one where the addresses have been looked up and converted to - presentation strings. - - -=-= - - profile should take traces of pointers to presentation objects without knowing anything about these presentation objects. - - For each stack node, compute a presentation object - (probably need to export opaque stacknode objects - with set/get_user_data) + - Creating a profile is then - - Send each stack trace to the profile module, along with - presentation objects. Maybe just a map from stack nodes - to presentation objects. + - For each stack node, compute a presentation object + (probably need to export opaque stacknode objects + with set/get_user_data) + + - Send each stack trace to the profile module, along with + presentation objects. Maybe just a map from stack nodes + to presentation objects. - Charge 'self' properly to processes that don't get any stack trace at all (probably we get that for free with stackstash reorganisation) @@ -427,42 +446,8 @@ Later: The disk timeline should probably vary in intensity with the number of outstanding disk requests. - - DONE: -Before 1.0: - - - Update version numbers in source - - - Make tarball - - - Check that tarball works - - - cvs commit - - - cvs tag sysprof-1-0 - - - Update website - - - Announce on Freshmeat - - - Announce on gnome-announce - - Announce on kernel list. - - - Announce on Gnomefiles - - - Announce on news.gnome.org - - Send to slashdot/developers - - Announce on devtools list (?) - - - Announce on Advogato - link to archive - -* The handling of the global variable in signal-handler.[ch] needs to be - atomic - right now it isn't. The issue is what happens if a handled signal - arrives while we are manipulating the list? - * (User space stack must probably be done in a thread - kernel stack must probably be taken in the interrupt itself? - Why this difference? The page tables should still be loaded. Is it diff --git a/profile.c b/profile.c index 5ebd0a64..f3dd0e97 100644 --- a/profile.c +++ b/profile.c @@ -349,12 +349,10 @@ struct Info }; static void -generate_object_table (GSList *trace, gint size, gpointer data) +generate_object_table (Process *process, GSList *trace, gint size, gpointer data) { Info *info = data; GSList *list; - Process *process = trace->data; - trace = trace->next; ensure_profile_object (info->profile_objects, process, 0); @@ -446,14 +444,12 @@ dump_trace (GSList *trace) #endif static void -generate_call_tree (GSList *trace, gint size, gpointer data) +generate_call_tree (Process *process, GSList *trace, gint size, gpointer data) { Info *info = data; Node *match = NULL; - GHashTable *seen_objects; - Process *process = trace->data; - trace = trace->next; ProfileObject *proc = lookup_profile_object (info->profile_objects, process, 0); + GHashTable *seen_objects; for (match = info->profile->call_tree; match; match = match->siblings) { diff --git a/stackstash.c b/stackstash.c index a1527d0f..c7ecb1d5 100644 --- a/stackstash.c +++ b/stackstash.c @@ -27,12 +27,14 @@ struct StackNode gpointer address; StackNode * siblings; StackNode * children; + StackNode * next; /* next leaf with the same pid */ int size; }; struct StackStash { StackNode *root; + GHashTable *leaves_by_process; }; static StackNode * @@ -43,6 +45,7 @@ stack_node_new (void) node->children = NULL; node->address = NULL; node->parent = NULL; + node->next = NULL; node->size = 0; return node; } @@ -65,6 +68,8 @@ stack_stash_new (void) { StackStash *stash = g_new (StackStash, 1); + stash->leaves_by_process = + g_hash_table_new (g_direct_hash, g_direct_equal); stash->root = NULL; return stash; } @@ -72,18 +77,32 @@ stack_stash_new (void) static StackNode * stack_node_add_trace (StackNode *node, GList *bottom, - gint size) + gint size, + StackNode **leaf) { StackNode *match; StackNode *n; if (!bottom) - return node; - - for (match = node; match != NULL; match = match->siblings) { - if (match->address == bottom->data) - break; + *leaf = NULL; + return node; + } + + if (!bottom->next) + { + /* A leaf must always be separate, so pids can + * point to them + */ + match = NULL; + } + else + { + for (match = node; match != NULL; match = match->siblings) + { + if (match->address == bottom->data) + break; + } } if (!match) @@ -95,57 +114,71 @@ stack_node_add_trace (StackNode *node, } match->children = - stack_node_add_trace (match->children, bottom->next, size); + stack_node_add_trace (match->children, bottom->next, size, leaf); for (n = match->children; n; n = n->siblings) n->parent = match; if (!bottom->next) + { match->size += size; + *leaf = match; + } return node; } void stack_stash_add_trace (StackStash *stash, + Process *process, gulong *addrs, int n_addrs, int size) { GList *trace; + StackNode *leaf; int i; trace = NULL; for (i = 0; i < n_addrs; ++i) trace = g_list_prepend (trace, GINT_TO_POINTER (addrs[i])); - stash->root = stack_node_add_trace (stash->root, trace, size); + stash->root = stack_node_add_trace (stash->root, trace, size, &leaf); + + leaf->next = g_hash_table_lookup ( + stash->leaves_by_process, process); + g_hash_table_insert ( + stash->leaves_by_process, process, leaf); g_list_free (trace); } -static void -do_callback (StackNode *node, - StackFunction stack_func, - gpointer data) +typedef struct CallbackInfo { - if (!node) - return; + StackFunction func; + gpointer data; +} CallbackInfo; - do_callback (node->siblings, stack_func, data); - do_callback (node->children, stack_func, data); - - if (!node->children) +static void +do_callback (gpointer key, gpointer value, gpointer data) +{ + CallbackInfo *info = data; + Process *process = key; + StackNode *n; + StackNode *leaf = value; + while (leaf) { - StackNode *n; - GSList *trace = NULL; + GSList *trace; - for (n = node; n != NULL; n = n->parent) + trace = NULL; + for (n = leaf; n; n = n->parent) trace = g_slist_prepend (trace, n->address); - stack_func (trace, node->size, data); + info->func (process, trace, leaf->size, info->data); g_slist_free (trace); + + leaf = leaf->next; } } @@ -154,7 +187,11 @@ stack_stash_foreach (StackStash *stash, StackFunction stack_func, gpointer data) { - do_callback (stash->root, stack_func, data); + CallbackInfo info; + info.func = stack_func; + info.data = data; + + g_hash_table_foreach (stash->leaves_by_process, do_callback, &info); } static void @@ -173,5 +210,6 @@ void stack_stash_free (StackStash *stash) { stack_node_free (stash->root); + g_hash_table_destroy (stash->leaves_by_process); g_free (stash); } diff --git a/stackstash.h b/stackstash.h index e79022da..aa058e1d 100644 --- a/stackstash.h +++ b/stackstash.h @@ -25,13 +25,15 @@ typedef struct StackStash StackStash; -typedef void (* StackFunction) (GSList *trace, +typedef void (* StackFunction) (Process *process, + GSList *trace, gint size, gpointer data); /* Stach */ StackStash *stack_stash_new (void); void stack_stash_add_trace (StackStash *stash, + Process *process, gulong *addrs, gint n_addrs, int size); diff --git a/sysprof-text.c b/sysprof-text.c index 6e5261c0..74a09c5d 100644 --- a/sysprof-text.c +++ b/sysprof-text.c @@ -57,8 +57,10 @@ read_trace (StackStash *stash, process_ensure_map (process, trace->pid, (gulong)trace->addresses[i]); } - - add_trace_to_stash (&trace, stash); + + stack_stash_add_trace ( + stash, process, + (gulong *)trace->addresses, trace->n_addresses, 1); } void diff --git a/sysprof.c b/sysprof.c index c97e5eea..680c9a8c 100644 --- a/sysprof.c +++ b/sysprof.c @@ -266,7 +266,7 @@ time_diff (const GTimeVal *first, return first_ms - second_ms; } -#define RESET_DEAD_PERIOD 5 +#define RESET_DEAD_PERIOD 25 static void on_read (gpointer data) @@ -302,8 +302,24 @@ on_read (gpointer data) if (rd > 0 && !app->generating_profile) { - add_trace_to_stash (&trace, app->stash); - + Process *process = process_get_from_pid (trace.pid); + int i; +/* char *filename = NULL; */ + +/* if (*trace.filename) */ +/* filename = trace.filename; */ + + for (i = 0; i < trace.n_addresses; ++i) + { + process_ensure_map (process, trace.pid, + (gulong)trace.addresses[i]); + } + g_assert (!app->generating_profile); + + stack_stash_add_trace ( + app->stash, process, + (gulong *)trace.addresses, trace.n_addresses, 1); + app->n_samples++; }