mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
Update
Sat Oct 1 01:21:57 2005 Soeren Sandmann <sandmann@redhat.com> * TODO: Update
This commit is contained in:
committed by
Søren Sandmann Pedersen
parent
1b21157a12
commit
cc1055d105
@ -1,3 +1,7 @@
|
||||
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>
|
||||
|
||||
* sysprof-text.c: Add my name to the copyright statement
|
||||
|
||||
@ -15,6 +15,8 @@ sysprof_SOURCES = \
|
||||
sfile.c \
|
||||
stackstash.h \
|
||||
stackstash.c \
|
||||
helper.c \
|
||||
helper.h \
|
||||
module/sysprof-module.h \
|
||||
sysprof.c \
|
||||
treeviewutils.h \
|
||||
@ -33,6 +35,8 @@ sysprof_text_SOURCES = \
|
||||
sfile.c \
|
||||
stackstash.h \
|
||||
stackstash.c \
|
||||
helper.c \
|
||||
helper.h \
|
||||
module/sysprof-module.h \
|
||||
signal-handler.h \
|
||||
signal-handler.c \
|
||||
|
||||
97
TODO
97
TODO
@ -1,35 +1,8 @@
|
||||
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
|
||||
@ -43,10 +16,6 @@ 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
|
||||
@ -205,23 +174,35 @@ 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.
|
||||
|
||||
- Creating a profile is then
|
||||
- For each stack node, compute a presentation object
|
||||
(probably need to export opaque stacknode objects
|
||||
with set/get_user_data)
|
||||
|
||||
- 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.
|
||||
- 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)
|
||||
@ -446,8 +427,42 @@ 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
|
||||
|
||||
10
profile.c
10
profile.c
@ -349,10 +349,12 @@ struct Info
|
||||
};
|
||||
|
||||
static void
|
||||
generate_object_table (Process *process, GSList *trace, gint size, gpointer data)
|
||||
generate_object_table (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);
|
||||
|
||||
@ -444,12 +446,14 @@ dump_trace (GSList *trace)
|
||||
#endif
|
||||
|
||||
static void
|
||||
generate_call_tree (Process *process, GSList *trace, gint size, gpointer data)
|
||||
generate_call_tree (GSList *trace, gint size, gpointer data)
|
||||
{
|
||||
Info *info = data;
|
||||
Node *match = NULL;
|
||||
ProfileObject *proc = lookup_profile_object (info->profile_objects, process, 0);
|
||||
GHashTable *seen_objects;
|
||||
Process *process = trace->data;
|
||||
trace = trace->next;
|
||||
ProfileObject *proc = lookup_profile_object (info->profile_objects, process, 0);
|
||||
|
||||
for (match = info->profile->call_tree; match; match = match->siblings)
|
||||
{
|
||||
|
||||
82
stackstash.c
82
stackstash.c
@ -27,14 +27,12 @@ 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 *
|
||||
@ -45,7 +43,6 @@ stack_node_new (void)
|
||||
node->children = NULL;
|
||||
node->address = NULL;
|
||||
node->parent = NULL;
|
||||
node->next = NULL;
|
||||
node->size = 0;
|
||||
return node;
|
||||
}
|
||||
@ -68,8 +65,6 @@ 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;
|
||||
}
|
||||
@ -77,32 +72,18 @@ stack_stash_new (void)
|
||||
static StackNode *
|
||||
stack_node_add_trace (StackNode *node,
|
||||
GList *bottom,
|
||||
gint size,
|
||||
StackNode **leaf)
|
||||
gint size)
|
||||
{
|
||||
StackNode *match;
|
||||
StackNode *n;
|
||||
|
||||
if (!bottom)
|
||||
{
|
||||
*leaf = NULL;
|
||||
return node;
|
||||
}
|
||||
|
||||
if (!bottom->next)
|
||||
for (match = node; match != NULL; match = match->siblings)
|
||||
{
|
||||
/* 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->address == bottom->data)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!match)
|
||||
@ -114,71 +95,57 @@ stack_node_add_trace (StackNode *node,
|
||||
}
|
||||
|
||||
match->children =
|
||||
stack_node_add_trace (match->children, bottom->next, size, leaf);
|
||||
stack_node_add_trace (match->children, bottom->next, size);
|
||||
|
||||
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, &leaf);
|
||||
|
||||
leaf->next = g_hash_table_lookup (
|
||||
stash->leaves_by_process, process);
|
||||
g_hash_table_insert (
|
||||
stash->leaves_by_process, process, leaf);
|
||||
stash->root = stack_node_add_trace (stash->root, trace, size);
|
||||
|
||||
g_list_free (trace);
|
||||
}
|
||||
|
||||
typedef struct CallbackInfo
|
||||
{
|
||||
StackFunction func;
|
||||
gpointer data;
|
||||
} CallbackInfo;
|
||||
|
||||
static void
|
||||
do_callback (gpointer key, gpointer value, gpointer data)
|
||||
do_callback (StackNode *node,
|
||||
StackFunction stack_func,
|
||||
gpointer data)
|
||||
{
|
||||
CallbackInfo *info = data;
|
||||
Process *process = key;
|
||||
StackNode *n;
|
||||
StackNode *leaf = value;
|
||||
while (leaf)
|
||||
{
|
||||
GSList *trace;
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
trace = NULL;
|
||||
for (n = leaf; n; n = n->parent)
|
||||
do_callback (node->siblings, stack_func, data);
|
||||
do_callback (node->children, stack_func, data);
|
||||
|
||||
if (!node->children)
|
||||
{
|
||||
StackNode *n;
|
||||
GSList *trace = NULL;
|
||||
|
||||
for (n = node; n != NULL; n = n->parent)
|
||||
trace = g_slist_prepend (trace, n->address);
|
||||
|
||||
info->func (process, trace, leaf->size, info->data);
|
||||
stack_func (trace, node->size, data);
|
||||
|
||||
g_slist_free (trace);
|
||||
|
||||
leaf = leaf->next;
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,11 +154,7 @@ stack_stash_foreach (StackStash *stash,
|
||||
StackFunction stack_func,
|
||||
gpointer data)
|
||||
{
|
||||
CallbackInfo info;
|
||||
info.func = stack_func;
|
||||
info.data = data;
|
||||
|
||||
g_hash_table_foreach (stash->leaves_by_process, do_callback, &info);
|
||||
do_callback (stash->root, stack_func, data);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -210,6 +173,5 @@ void
|
||||
stack_stash_free (StackStash *stash)
|
||||
{
|
||||
stack_node_free (stash->root);
|
||||
g_hash_table_destroy (stash->leaves_by_process);
|
||||
g_free (stash);
|
||||
}
|
||||
|
||||
@ -25,15 +25,13 @@
|
||||
|
||||
typedef struct StackStash StackStash;
|
||||
|
||||
typedef void (* StackFunction) (Process *process,
|
||||
GSList *trace,
|
||||
typedef void (* StackFunction) (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);
|
||||
|
||||
@ -57,10 +57,8 @@ read_trace (StackStash *stash,
|
||||
process_ensure_map (process, trace->pid,
|
||||
(gulong)trace->addresses[i]);
|
||||
}
|
||||
|
||||
stack_stash_add_trace (
|
||||
stash, process,
|
||||
(gulong *)trace->addresses, trace->n_addresses, 1);
|
||||
|
||||
add_trace_to_stash (&trace, stash);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
22
sysprof.c
22
sysprof.c
@ -266,7 +266,7 @@ time_diff (const GTimeVal *first,
|
||||
return first_ms - second_ms;
|
||||
}
|
||||
|
||||
#define RESET_DEAD_PERIOD 25
|
||||
#define RESET_DEAD_PERIOD 5
|
||||
|
||||
static void
|
||||
on_read (gpointer data)
|
||||
@ -302,24 +302,8 @@ on_read (gpointer data)
|
||||
|
||||
if (rd > 0 && !app->generating_profile)
|
||||
{
|
||||
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);
|
||||
|
||||
add_trace_to_stash (&trace, app->stash);
|
||||
|
||||
app->n_samples++;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user