perf stat aggregation: Add separate core member
[linux-2.6-microblaze.git] / tools / perf / builtin-stat.c
index 1ff76d3..8cc2496 100644 (file)
@@ -1221,10 +1221,10 @@ static struct aggr_cpu_id perf_stat__get_aggr(struct perf_stat_config *config,
 
        cpu = map->map[idx];
 
-       if (config->cpus_aggr_map->map[cpu] == -1)
-               config->cpus_aggr_map->map[cpu] = get_id(config, map, idx).id;
+       if (cpu_map__aggr_cpu_id_is_empty(config->cpus_aggr_map->map[cpu]))
+               config->cpus_aggr_map->map[cpu] = get_id(config, map, idx);
 
-       id.id = config->cpus_aggr_map->map[cpu];
+       id = config->cpus_aggr_map->map[cpu];
        return id;
 }
 
@@ -1320,14 +1320,29 @@ static int perf_stat_init_aggr_mode(void)
         * the aggregation translate cpumap.
         */
        nr = perf_cpu_map__max(evsel_list->core.cpus);
-       stat_config.cpus_aggr_map = perf_cpu_map__empty_new(nr + 1);
+       stat_config.cpus_aggr_map = cpu_aggr_map__empty_new(nr + 1);
        return stat_config.cpus_aggr_map ? 0 : -ENOMEM;
 }
 
+static void cpu_aggr_map__delete(struct cpu_aggr_map *map)
+{
+       if (map) {
+               WARN_ONCE(refcount_read(&map->refcnt) != 0,
+                         "cpu_aggr_map refcnt unbalanced\n");
+               free(map);
+       }
+}
+
+static void cpu_aggr_map__put(struct cpu_aggr_map *map)
+{
+       if (map && refcount_dec_and_test(&map->refcnt))
+               cpu_aggr_map__delete(map);
+}
+
 static void perf_stat__exit_aggr_mode(void)
 {
-       perf_cpu_map__put(stat_config.aggr_map);
-       perf_cpu_map__put(stat_config.cpus_aggr_map);
+       cpu_aggr_map__put(stat_config.aggr_map);
+       cpu_aggr_map__put(stat_config.cpus_aggr_map);
        stat_config.aggr_map = NULL;
        stat_config.cpus_aggr_map = NULL;
 }
@@ -1354,7 +1369,7 @@ static struct aggr_cpu_id perf_env__get_socket(struct perf_cpu_map *map, int idx
        struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
 
        if (cpu != -1)
-               id.id = env->cpu[cpu].socket_id;
+               id.socket = env->cpu[cpu].socket_id;
 
        return id;
 }
@@ -1367,18 +1382,12 @@ static struct aggr_cpu_id perf_env__get_die(struct perf_cpu_map *map, int idx, v
 
        if (cpu != -1) {
                /*
-                * Encode socket in bit range 15:8
-                * die_id is relative to socket,
-                * we need a global id. So we combine
-                * socket + die id
+                * die_id is relative to socket, so start
+                * with the socket ID and then add die to
+                * make a unique ID.
                 */
-               if (WARN_ONCE(env->cpu[cpu].socket_id >> 8, "The socket id number is too big.\n"))
-                       return cpu_map__empty_aggr_cpu_id();
-
-               if (WARN_ONCE(env->cpu[cpu].die_id >> 8, "The die id number is too big.\n"))
-                       return cpu_map__empty_aggr_cpu_id();
-
-               id.id = (env->cpu[cpu].socket_id << 8) | (env->cpu[cpu].die_id & 0xff);
+               id.socket = env->cpu[cpu].socket_id;
+               id.die = env->cpu[cpu].die_id;
        }
 
        return id;
@@ -1392,24 +1401,13 @@ static struct aggr_cpu_id perf_env__get_core(struct perf_cpu_map *map, int idx,
 
        if (cpu != -1) {
                /*
-                * Encode socket in bit range 31:24
-                * encode die id in bit range 23:16
                 * core_id is relative to socket and die,
-                * we need a global id. So we combine
-                * socket + die id + core id
+                * we need a global id. So we set
+                * socket, die id and core id
                 */
-               if (WARN_ONCE(env->cpu[cpu].socket_id >> 8, "The socket id number is too big.\n"))
-                       return cpu_map__empty_aggr_cpu_id();
-
-               if (WARN_ONCE(env->cpu[cpu].die_id >> 8, "The die id number is too big.\n"))
-                       return cpu_map__empty_aggr_cpu_id();
-
-               if (WARN_ONCE(env->cpu[cpu].core_id >> 16, "The core id number is too big.\n"))
-                       return cpu_map__empty_aggr_cpu_id();
-
-               id.id = (env->cpu[cpu].socket_id << 24) |
-                      (env->cpu[cpu].die_id << 16) |
-                      (env->cpu[cpu].core_id & 0xffff);
+               id.socket = env->cpu[cpu].socket_id;
+               id.die = env->cpu[cpu].die_id;
+               id.core = env->cpu[cpu].core_id;
        }
 
        return id;
@@ -1420,30 +1418,30 @@ static struct aggr_cpu_id perf_env__get_node(struct perf_cpu_map *map, int idx,
        int cpu = perf_env__get_cpu(data, map, idx);
        struct aggr_cpu_id id = cpu_map__empty_aggr_cpu_id();
 
-       id.id = perf_env__numa_node(data, cpu);
+       id.node = perf_env__numa_node(data, cpu);
        return id;
 }
 
 static int perf_env__build_socket_map(struct perf_env *env, struct perf_cpu_map *cpus,
-                                     struct perf_cpu_map **sockp)
+                                     struct cpu_aggr_map **sockp)
 {
        return cpu_map__build_map(cpus, sockp, perf_env__get_socket, env);
 }
 
 static int perf_env__build_die_map(struct perf_env *env, struct perf_cpu_map *cpus,
-                                  struct perf_cpu_map **diep)
+                                  struct cpu_aggr_map **diep)
 {
        return cpu_map__build_map(cpus, diep, perf_env__get_die, env);
 }
 
 static int perf_env__build_core_map(struct perf_env *env, struct perf_cpu_map *cpus,
-                                   struct perf_cpu_map **corep)
+                                   struct cpu_aggr_map **corep)
 {
        return cpu_map__build_map(cpus, corep, perf_env__get_core, env);
 }
 
 static int perf_env__build_node_map(struct perf_env *env, struct perf_cpu_map *cpus,
-                                   struct perf_cpu_map **nodep)
+                                   struct cpu_aggr_map **nodep)
 {
        return cpu_map__build_map(cpus, nodep, perf_env__get_node, env);
 }