Revert accidental commit of stackstash reorganisation

This commit is contained in:
Søren Sandmann Pedersen
2005-10-01 05:23:58 +00:00
parent cc1055d105
commit f7e888e574
8 changed files with 131 additions and 100 deletions

View File

@ -1,7 +1,3 @@
Sat Oct 1 01:21:57 2005 Soeren Sandmann <sandmann@redhat.com>
* TODO: Update
Wed Sep 28 12:08:32 2005 Søren Sandmann <sandmann@redhat.com> Wed Sep 28 12:08:32 2005 Søren Sandmann <sandmann@redhat.com>
* sysprof-text.c: Add my name to the copyright statement * sysprof-text.c: Add my name to the copyright statement

View File

@ -15,8 +15,6 @@ sysprof_SOURCES = \
sfile.c \ sfile.c \
stackstash.h \ stackstash.h \
stackstash.c \ stackstash.c \
helper.c \
helper.h \
module/sysprof-module.h \ module/sysprof-module.h \
sysprof.c \ sysprof.c \
treeviewutils.h \ treeviewutils.h \
@ -35,8 +33,6 @@ sysprof_text_SOURCES = \
sfile.c \ sfile.c \
stackstash.h \ stackstash.h \
stackstash.c \ stackstash.c \
helper.c \
helper.h \
module/sysprof-module.h \ module/sysprof-module.h \
signal-handler.h \ signal-handler.h \
signal-handler.c \ signal-handler.c \

97
TODO
View File

@ -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: Before 1.0.1:
* See if we can reproduce the problem where libraries didn't get correctly * See if we can reproduce the problem where libraries didn't get correctly
reloaded after new versions were installed. reloaded after new versions were installed.
This is just the (deleted) problem.
* Build system * Build system
- Find out what distributions it actually works on - Find out what distributions it actually works on
@ -16,6 +43,10 @@ Before 1.0.1:
Before 1.2: 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. * Figure out how to make sfile.[ch] use less memory.
- In general clean sfile.[ch] up a little: - In general clean sfile.[ch] up a little:
- split out dfa in its own generic class - 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 - Reorganise stackstash and profile
- stackstash should just take traces of addresses without knowing - 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 - 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 - profile should take traces of pointers to presentation
objects without knowing anything about these presentation objects without knowing anything about these presentation
objects. objects.
- For each stack node, compute a presentation object - Creating a profile is then
(probably need to export opaque stacknode objects
with set/get_user_data)
- Send each stack trace to the profile module, along with - For each stack node, compute a presentation object
presentation objects. Maybe just a map from stack nodes (probably need to export opaque stacknode objects
to presentation 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 - Charge 'self' properly to processes that don't get any stack trace at all
(probably we get that for free with stackstash reorganisation) (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 The disk timeline should probably vary in intensity with the number of outstanding
disk requests. disk requests.
DONE: 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 * (User space stack must probably be done in a thread - kernel
stack must probably be taken in the interrupt itself? stack must probably be taken in the interrupt itself?
- Why this difference? The page tables should still be loaded. Is it - Why this difference? The page tables should still be loaded. Is it

View File

@ -349,12 +349,10 @@ struct Info
}; };
static void 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; Info *info = data;
GSList *list; GSList *list;
Process *process = trace->data;
trace = trace->next;
ensure_profile_object (info->profile_objects, process, 0); ensure_profile_object (info->profile_objects, process, 0);
@ -446,14 +444,12 @@ dump_trace (GSList *trace)
#endif #endif
static void 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; Info *info = data;
Node *match = NULL; Node *match = NULL;
GHashTable *seen_objects;
Process *process = trace->data;
trace = trace->next;
ProfileObject *proc = lookup_profile_object (info->profile_objects, process, 0); ProfileObject *proc = lookup_profile_object (info->profile_objects, process, 0);
GHashTable *seen_objects;
for (match = info->profile->call_tree; match; match = match->siblings) for (match = info->profile->call_tree; match; match = match->siblings)
{ {

View File

@ -27,12 +27,14 @@ struct StackNode
gpointer address; gpointer address;
StackNode * siblings; StackNode * siblings;
StackNode * children; StackNode * children;
StackNode * next; /* next leaf with the same pid */
int size; int size;
}; };
struct StackStash struct StackStash
{ {
StackNode *root; StackNode *root;
GHashTable *leaves_by_process;
}; };
static StackNode * static StackNode *
@ -43,6 +45,7 @@ stack_node_new (void)
node->children = NULL; node->children = NULL;
node->address = NULL; node->address = NULL;
node->parent = NULL; node->parent = NULL;
node->next = NULL;
node->size = 0; node->size = 0;
return node; return node;
} }
@ -65,6 +68,8 @@ stack_stash_new (void)
{ {
StackStash *stash = g_new (StackStash, 1); StackStash *stash = g_new (StackStash, 1);
stash->leaves_by_process =
g_hash_table_new (g_direct_hash, g_direct_equal);
stash->root = NULL; stash->root = NULL;
return stash; return stash;
} }
@ -72,18 +77,32 @@ stack_stash_new (void)
static StackNode * static StackNode *
stack_node_add_trace (StackNode *node, stack_node_add_trace (StackNode *node,
GList *bottom, GList *bottom,
gint size) gint size,
StackNode **leaf)
{ {
StackNode *match; StackNode *match;
StackNode *n; StackNode *n;
if (!bottom) if (!bottom)
return node;
for (match = node; match != NULL; match = match->siblings)
{ {
if (match->address == bottom->data) *leaf = NULL;
break; 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) if (!match)
@ -95,57 +114,71 @@ stack_node_add_trace (StackNode *node,
} }
match->children = 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) for (n = match->children; n; n = n->siblings)
n->parent = match; n->parent = match;
if (!bottom->next) if (!bottom->next)
{
match->size += size; match->size += size;
*leaf = match;
}
return node; return node;
} }
void void
stack_stash_add_trace (StackStash *stash, stack_stash_add_trace (StackStash *stash,
Process *process,
gulong *addrs, gulong *addrs,
int n_addrs, int n_addrs,
int size) int size)
{ {
GList *trace; GList *trace;
StackNode *leaf;
int i; int i;
trace = NULL; trace = NULL;
for (i = 0; i < n_addrs; ++i) for (i = 0; i < n_addrs; ++i)
trace = g_list_prepend (trace, GINT_TO_POINTER (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); g_list_free (trace);
} }
static void typedef struct CallbackInfo
do_callback (StackNode *node,
StackFunction stack_func,
gpointer data)
{ {
if (!node) StackFunction func;
return; gpointer data;
} CallbackInfo;
do_callback (node->siblings, stack_func, data); static void
do_callback (node->children, stack_func, data); do_callback (gpointer key, gpointer value, gpointer data)
{
if (!node->children) CallbackInfo *info = data;
Process *process = key;
StackNode *n;
StackNode *leaf = value;
while (leaf)
{ {
StackNode *n; GSList *trace;
GSList *trace = NULL;
for (n = node; n != NULL; n = n->parent) trace = NULL;
for (n = leaf; n; n = n->parent)
trace = g_slist_prepend (trace, n->address); 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); g_slist_free (trace);
leaf = leaf->next;
} }
} }
@ -154,7 +187,11 @@ stack_stash_foreach (StackStash *stash,
StackFunction stack_func, StackFunction stack_func,
gpointer data) 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 static void
@ -173,5 +210,6 @@ void
stack_stash_free (StackStash *stash) stack_stash_free (StackStash *stash)
{ {
stack_node_free (stash->root); stack_node_free (stash->root);
g_hash_table_destroy (stash->leaves_by_process);
g_free (stash); g_free (stash);
} }

View File

@ -25,13 +25,15 @@
typedef struct StackStash StackStash; typedef struct StackStash StackStash;
typedef void (* StackFunction) (GSList *trace, typedef void (* StackFunction) (Process *process,
GSList *trace,
gint size, gint size,
gpointer data); gpointer data);
/* Stach */ /* Stach */
StackStash *stack_stash_new (void); StackStash *stack_stash_new (void);
void stack_stash_add_trace (StackStash *stash, void stack_stash_add_trace (StackStash *stash,
Process *process,
gulong *addrs, gulong *addrs,
gint n_addrs, gint n_addrs,
int size); int size);

View File

@ -57,8 +57,10 @@ read_trace (StackStash *stash,
process_ensure_map (process, trace->pid, process_ensure_map (process, trace->pid,
(gulong)trace->addresses[i]); (gulong)trace->addresses[i]);
} }
add_trace_to_stash (&trace, stash); stack_stash_add_trace (
stash, process,
(gulong *)trace->addresses, trace->n_addresses, 1);
} }
void void

View File

@ -266,7 +266,7 @@ time_diff (const GTimeVal *first,
return first_ms - second_ms; return first_ms - second_ms;
} }
#define RESET_DEAD_PERIOD 5 #define RESET_DEAD_PERIOD 25
static void static void
on_read (gpointer data) on_read (gpointer data)
@ -302,8 +302,24 @@ on_read (gpointer data)
if (rd > 0 && !app->generating_profile) 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++; app->n_samples++;
} }