From d1a082ffec6f2e4f40ae9afbed10689d122f6c64 Mon Sep 17 00:00:00 2001 From: Soren Sandmann Date: Mon, 20 Nov 2006 07:25:02 +0000 Subject: [PATCH] reset the collector after generating the profile. 2006-11-20 Soren Sandmann * sysprof.c (ensure_profile): reset the collector after generating the profile. * stackstash.c (struct StackStash): Add cached_nodes and blocks. (stack_node_new): Allocate stack nodes in blocks. --- ChangeLog | 8 ++++ collector.c | 2 +- profile.c | 2 +- stackstash.c | 104 +++++++++++++++++++++++++++++++-------------------- stackstash.h | 2 +- sysprof.c | 1 + 6 files changed, 75 insertions(+), 44 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2f68214c..89db255a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-11-20 Soren Sandmann + + * sysprof.c (ensure_profile): reset the collector after generating + the profile. + + * stackstash.c (struct StackStash): Add cached_nodes and blocks. + (stack_node_new): Allocate stack nodes in blocks. + 2006-11-19 Soren Sandmann * profile.c (profile_load): Use stack allocated variables to avoid diff --git a/collector.c b/collector.c index 8bf737a6..90635844 100644 --- a/collector.c +++ b/collector.c @@ -398,7 +398,7 @@ collector_create_profile (Collector *collector) profile = profile_new (info.resolved_stash); stack_stash_unref (info.resolved_stash); - + return profile; } diff --git a/profile.c b/profile.c index 952674b4..4c810caf 100644 --- a/profile.c +++ b/profile.c @@ -205,7 +205,7 @@ profile_load (const char *filename, GError **err) n = sfile_begin_get_list (input, "nodes"); for (i = 0; i < n; ++i) { - StackNode *node = stack_node_new (); + StackNode *node = stack_node_new (profile->stash); gboolean toplevel; gint32 size; gint32 total; diff --git a/stackstash.c b/stackstash.c index dd09069a..1844946b 100644 --- a/stackstash.c +++ b/stackstash.c @@ -25,12 +25,36 @@ struct StackStash StackNode * root; GHashTable * nodes_by_data; GDestroyNotify destroy; + + StackNode * cached_nodes; + GPtrArray * blocks; }; StackNode * -stack_node_new (void) +stack_node_new (StackStash *stash) { - StackNode *node = g_new (StackNode, 1); + StackNode *node; + + if (!stash->cached_nodes) + { +#define BLOCK_SIZE 32768 +#define N_NODES (BLOCK_SIZE / sizeof (StackNode)) + + StackNode *block = g_malloc (BLOCK_SIZE); + int i; + + for (i = 0; i < N_NODES; ++i) + { + block[i].next = stash->cached_nodes; + stash->cached_nodes = &(block[i]); + } + + g_ptr_array_add (stash->blocks, block); + } + + node = stash->cached_nodes; + stash->cached_nodes = node->next; + node->siblings = NULL; node->children = NULL; node->address = NULL; @@ -38,6 +62,7 @@ stack_node_new (void) node->size = 0; node->next = NULL; node->total = 0; + return node; } @@ -51,6 +76,9 @@ create_stack_stash (GDestroyNotify destroy) stash->nodes_by_data = g_hash_table_new (g_direct_hash, g_direct_equal); stash->ref_count = 1; stash->destroy = destroy; + + stash->cached_nodes = NULL; + stash->blocks = g_ptr_array_new (); return stash; } @@ -62,6 +90,38 @@ stack_stash_new (GDestroyNotify destroy) return create_stack_stash (destroy); } + +static void +free_key (gpointer key, + gpointer value, + gpointer data) +{ + GDestroyNotify destroy = data; + + destroy (key); +} + +static void +stack_stash_free (StackStash *stash) +{ + int i; + + if (stash->destroy) + { + g_hash_table_foreach (stash->nodes_by_data, free_key, + stash->destroy); + } + + g_hash_table_destroy (stash->nodes_by_data); + + for (i = 0; i < stash->blocks->len; ++i) + g_free (stash->blocks->pdata[i]); + + g_ptr_array_free (stash->blocks, TRUE); + + g_free (stash); +} + static void decorate_node (StackStash *stash, StackNode *node) @@ -118,7 +178,7 @@ stack_stash_add_trace (StackStash *stash, if (!match) { - match = stack_node_new (); + match = stack_node_new (stash); match->address = (gpointer)addrs[i]; match->siblings = *location; match->parent = parent; @@ -186,44 +246,6 @@ stack_node_foreach_trace (StackNode *node, do_callback (node->children, &link, func, data); } -static void -stack_node_free (StackNode *node) -{ - if (!node) - return; - - stack_node_free (node->siblings); - stack_node_free (node->children); - - g_free (node); -} - -static void -free_key (gpointer key, - gpointer value, - gpointer data) -{ - GDestroyNotify destroy = data; - - destroy (key); -} - -static void -stack_stash_free (StackStash *stash) -{ - stack_node_free (stash->root); - - if (stash->destroy) - { - g_hash_table_foreach (stash->nodes_by_data, free_key, - stash->destroy); - } - - g_hash_table_destroy (stash->nodes_by_data); - - g_free (stash); -} - void stack_stash_unref (StackStash *stash) { diff --git a/stackstash.h b/stackstash.h index c6f7bda5..b04eb3f2 100644 --- a/stackstash.h +++ b/stackstash.h @@ -49,7 +49,7 @@ typedef void (* StackNodeFunc) (StackNode *node, /* Stach */ StackStash *stack_stash_new (GDestroyNotify destroy); -StackNode * stack_node_new (void); +StackNode * stack_node_new (StackStash *stash); void stack_stash_add_trace (StackStash *stash, gulong *addrs, gint n_addrs, diff --git a/sysprof.c b/sysprof.c index 156bcdf5..c833da8a 100644 --- a/sysprof.c +++ b/sysprof.c @@ -656,6 +656,7 @@ ensure_profile (Application *app) app->profile = collector_create_profile (app->collector); collector_stop (app->collector); + collector_reset (app->collector); fill_lists (app);