summaryrefslogtreecommitdiff
path: root/tools/perf/util/map.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/map.c')
-rw-r--r--tools/perf/util/map.c49
1 files changed, 46 insertions, 3 deletions
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index d0899df77baa..67e0f81416cb 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -573,20 +573,63 @@ void map_groups__init(struct map_groups *mg, struct machine *machine)
maps__init(&mg->maps);
mg->machine = machine;
mg->last_search_by_name = NULL;
+ mg->nr_maps = 0;
+ mg->maps_by_name = NULL;
refcount_set(&mg->refcnt, 1);
}
+static void __map_groups__free_maps_by_name(struct map_groups *mg)
+{
+ /*
+ * Free everything to try to do it from the rbtree in the next search
+ */
+ zfree(&mg->maps_by_name);
+ mg->nr_maps_allocated = 0;
+}
+
void map_groups__insert(struct map_groups *mg, struct map *map)
{
- maps__insert(&mg->maps, map);
+ struct maps *maps = &mg->maps;
+
+ down_write(&maps->lock);
+ __maps__insert(maps, map);
+ ++mg->nr_maps;
+
+ /*
+ * If we already performed some search by name, then we need to add the just
+ * inserted map and resort.
+ */
+ if (mg->maps_by_name) {
+ if (mg->nr_maps > mg->nr_maps_allocated) {
+ int nr_allocate = mg->nr_maps * 2;
+ struct map **maps_by_name = realloc(mg->maps_by_name, nr_allocate * sizeof(map));
+
+ if (maps_by_name == NULL) {
+ __map_groups__free_maps_by_name(mg);
+ return;
+ }
+
+ mg->maps_by_name = maps_by_name;
+ mg->nr_maps_allocated = nr_allocate;
+ }
+ mg->maps_by_name[mg->nr_maps - 1] = map;
+ __map_groups__sort_by_name(mg);
+ }
+ up_write(&maps->lock);
}
void map_groups__remove(struct map_groups *mg, struct map *map)
{
+ struct maps *maps = &mg->maps;
+ down_write(&maps->lock);
if (mg->last_search_by_name == map)
mg->last_search_by_name = NULL;
- maps__remove(&mg->maps, map);
+ __maps__remove(maps, map);
+ --mg->nr_maps;
+ if (mg->maps_by_name)
+ __map_groups__free_maps_by_name(mg);
+ up_write(&maps->lock);
}
static void __maps__purge(struct maps *maps)
@@ -904,7 +947,7 @@ void maps__insert(struct maps *maps, struct map *map)
up_write(&maps->lock);
}
-static void __maps__remove(struct maps *maps, struct map *map)
+void __maps__remove(struct maps *maps, struct map *map)
{
rb_erase_init(&map->rb_node, &maps->entries);
map__put(map);