summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <sandmann@daimi.au.dk>2010-11-09 06:32:14 -0500
committerSøren Sandmann Pedersen <sandmann@daimi.au.dk>2011-01-27 17:00:02 -0500
commitf594fad6b06066484d35eae293e5add3190a777c (patch)
treec1bb77535b4cea502ba04e51979e75f59dbc4f71
parent395f527c8326e50cfa705f6afc1c6faf4fcde07b (diff)
Speed up map locating in tracker.c
Store the maps as a GArray rather than a GPtrArray to improve locality; also move maps to front when they are looked up.
-rw-r--r--tracker.c100
1 files changed, 47 insertions, 53 deletions
diff --git a/tracker.c b/tracker.c
index 9117052..49ba459 100644
--- a/tracker.c
+++ b/tracker.c
@@ -385,7 +385,7 @@ struct process_t
char * comm;
- GPtrArray * maps;
+ GArray * maps;
};
struct map_t
@@ -405,18 +405,38 @@ struct state_t
GHashTable *bin_files;
};
-static void
-destroy_map (map_t *map)
+static const map_t *
+process_locate_map (process_t *process, gulong addr)
{
- g_free (map->filename);
- g_free (map);
+ GArray *maps = process->maps;
+ int i;
+
+ for (i = 0; i < process->maps->len; ++i)
+ {
+ map_t *map = &g_array_index (maps, map_t, i);
+
+ if (addr >= map->start && addr < map->end && i > 0)
+ {
+ map_t tmp = *map;
+
+ memmove (&(g_array_index (maps, map_t, 1)),
+ &(g_array_index (maps, map_t, 0)),
+ i * sizeof (map_t));
+
+ g_array_index (maps, map_t, 0) = tmp;
+
+ return &g_array_index (maps, map_t, 0);
+ }
+ }
+
+ return NULL;
}
static void
create_map (state_t *state, new_map_t *new_map)
{
process_t *process;
- map_t *map;
+ map_t map;
int i;
pid_t pid = GET_PID (new_map->header);
@@ -426,27 +446,26 @@ create_map (state_t *state, new_map_t *new_map)
if (!process)
return;
- map = g_new0 (map_t, 1);
- map->filename = g_strdup (new_map->filename);
- map->start = new_map->start;
- map->end = new_map->end;
- map->offset = new_map->offset;
- map->inode = new_map->inode;
+ map.filename = g_strdup (new_map->filename);
+ map.start = new_map->start;
+ map.end = new_map->end;
+ map.offset = new_map->offset;
+ map.inode = new_map->inode;
/* Remove existing maps that overlap the new one */
for (i = 0; i < process->maps->len; ++i)
{
- map_t *m = process->maps->pdata[i];
+ map_t *m = &g_array_index (process->maps, map_t, i);
- if (m->start < map->end && m->end > map->start)
+ if (m->start < map.end && m->end > map.start)
{
- destroy_map (m);
+ g_free (m->filename);
- g_ptr_array_remove_index (process->maps, i);
+ g_array_remove_index (process->maps, i);
}
}
- g_ptr_array_add (process->maps, map);
+ g_array_append_vals (process->maps, &map, 1);
}
static void
@@ -458,12 +477,12 @@ destroy_process (process_t *process)
for (i = 0; i < process->maps->len; ++i)
{
- map_t *map = process->maps->pdata[i];
+ map_t *map = &g_array_index (process->maps, map_t, i);
- destroy_map (map);
+ g_free (map->filename);
}
- g_ptr_array_free (process->maps, TRUE);
+ g_array_free (process->maps, TRUE);
g_free (process);
}
@@ -487,24 +506,13 @@ create_process (state_t *state, new_process_t *new_process)
process->pid = pid;
process->comm = g_strdup (comm);
- process->maps = g_ptr_array_new ();
+ process->maps = g_array_new (FALSE, FALSE, sizeof (map_t));
g_hash_table_insert (
state->processes_by_pid, GINT_TO_POINTER (process->pid), process);
}
}
-static map_t *
-copy_map (map_t *map)
-{
- map_t *copy = g_new0 (map_t, 1);
-
- *copy = *map;
- copy->filename = g_strdup (map->filename);
-
- return copy;
-}
-
static void
process_fork (state_t *state, fork_t *fork)
{
@@ -528,7 +536,7 @@ process_fork (state_t *state, fork_t *fork)
child->pid = fork->child_pid;
- child->maps = g_ptr_array_new ();
+ child->maps = g_array_new (FALSE, FALSE, sizeof (map_t));
if (parent)
{
@@ -536,9 +544,11 @@ process_fork (state_t *state, fork_t *fork)
for (i = 0; i < parent->maps->len; ++i)
{
- map_t *map = copy_map (parent->maps->pdata[i]);
+ map_t copy = g_array_index (parent->maps, map_t, i);
+
+ copy.filename = g_strdup (copy.filename);
- g_ptr_array_add (child->maps, map);
+ g_array_append_val (child->maps, copy);
}
}
@@ -842,22 +852,6 @@ unique_dup (GHashTable *unique_symbols, const char *sym)
return result;
}
-static map_t *
-process_locate_map (process_t *process, gulong addr)
-{
- int i;
-
- for (i = 0; i < process->maps->len; ++i)
- {
- map_t *map = process->maps->pdata[i];
-
- if (addr >= map->start && addr < map->end)
- return map;
- }
-
- return NULL;
-}
-
static const char *
make_message (state_t *state, const char *format, ...)
{
@@ -915,7 +909,7 @@ lookup_symbol (state_t *state,
}
else
{
- map_t *map = process_locate_map (process, address);
+ const map_t *map = process_locate_map (process, address);
if (!map)
{
@@ -1119,7 +1113,7 @@ tracker_create_profile (tracker_t *tracker)
break;
}
}
-
+
profile = profile_new (resolved_stash);
state_free (state);