aboutsummaryrefslogtreecommitdiff
path: root/idlestat.c
diff options
context:
space:
mode:
authorTuukka Tikkanen <tuukka.tikkanen@linaro.org>2014-12-08 14:15:32 +0200
committerTuukka Tikkanen <tuukka.tikkanen@linaro.org>2014-12-12 08:55:39 +0200
commit663342ed3364d4855a967be5ebe680bb2b3ffdcf (patch)
tree1c8b81d99a09b53ee78d0f9f9df1cbafeb3717d4 /idlestat.c
parent257e64c12df95f199fb5f8e7195c6a19efaba7ca (diff)
topology: Dynamic allocation for topologies
Pre-patch the topology is rooted to a global variable g_cpu_topo_list. This prevents loading multiple traces for comparison. This patch makes the allocation dynamic. The root pointer is stored within struct cpuidle_datas, allowing the idlestat_load() to retain its prototype, but most of the functions defined in topology.c have a new parameter for passing the topology root pointer. Signed-off-by: Tuukka Tikkanen <tuukka.tikkanen@linaro.org> Reviewed-by: Koan-Sin Tan <freedom.tan@linaro.org>
Diffstat (limited to 'idlestat.c')
-rw-r--r--idlestat.c41
1 files changed, 27 insertions, 14 deletions
diff --git a/idlestat.c b/idlestat.c
index c9a0ef2..4ee6f57 100644
--- a/idlestat.c
+++ b/idlestat.c
@@ -1040,7 +1040,12 @@ struct cpuidle_datas *idlestat_load(const char *filename)
}
/* read topology information */
- read_cpu_topo_info(f, buffer);
+ datas->topo = read_cpu_topo_info(f, buffer);
+ if (is_err(datas->topo)) {
+ fclose(f);
+ free(datas);
+ return ptrerror(NULL);
+ }
datas->nrcpus = nrcpus;
@@ -1489,7 +1494,8 @@ static int idlestat_file_for_each_line(const char *path, void *data,
}
static int idlestat_store(const char *path, double start_ts, double end_ts,
- struct init_pstates *initp)
+ struct init_pstates *initp,
+ struct cpu_topology *cpu_topo)
{
FILE *f;
int ret;
@@ -1513,7 +1519,7 @@ static int idlestat_store(const char *path, double start_ts, double end_ts,
fprintf(f, "cpus=%d\n", ret);
/* output topology information */
- output_cpu_topo_info(f);
+ output_cpu_topo_info(cpu_topo, f);
/* output c-states information */
output_cstate_info(f, ret);
@@ -1643,6 +1649,7 @@ int main(int argc, char *argv[], char *const envp[])
double start_ts = 0, end_ts = 0;
struct init_pstates *initp = NULL;
struct report_ops *output_handler = NULL;
+ struct cpu_topology *cpu_topo = NULL;
args = getoptions(argc, argv, &options);
if (args <= 0)
@@ -1666,14 +1673,12 @@ int main(int argc, char *argv[], char *const envp[])
return 1;
}
- /* init cpu topoinfo */
- init_cpu_topo_info();
-
/* Acquisition time specified means we will get the traces */
if ((options.mode == TRACE) || args < argc) {
/* Read cpu topology info from sysfs */
- if (read_sysfs_cpu_topo()) {
+ cpu_topo = read_sysfs_cpu_topo();
+ if (is_err(cpu_topo)) {
fprintf(stderr, "Failed to read CPU topology info from"
" sysfs.\n");
return 1;
@@ -1734,8 +1739,14 @@ int main(int argc, char *argv[], char *const envp[])
* up all cpus and timer expiration for the timer
* acquisition). We assume these will be lost in the number
* of other traces and could be negligible. */
- if (idlestat_store(options.filename, start_ts, end_ts, initp))
+ if (idlestat_store(options.filename, start_ts, end_ts,
+ initp, cpu_topo))
return 1;
+
+ /* Discard topology, will be reloaded during trace load */
+ release_cpu_topo_cstates(cpu_topo);
+ release_cpu_topo_info(cpu_topo);
+ cpu_topo = NULL;
}
/* Load the idle states information */
@@ -1744,6 +1755,8 @@ int main(int argc, char *argv[], char *const envp[])
if (is_err(datas))
return 1;
+ cpu_topo = datas->topo;
+
/* Compute cluster idle intersection between cpus belonging to
* the same cluster
*/
@@ -1753,31 +1766,31 @@ int main(int argc, char *argv[], char *const envp[])
if (options.display & IDLE_DISPLAY) {
output_handler->cstate_table_header(options.report_data);
- dump_cpu_topo_info(output_handler, options.report_data, display_cstates, 1);
+ dump_cpu_topo_info(output_handler, options.report_data, display_cstates, cpu_topo, 1);
output_handler->cstate_table_footer(options.report_data);
}
if (options.display & FREQUENCY_DISPLAY) {
output_handler->pstate_table_header(options.report_data);
- dump_cpu_topo_info(output_handler, options.report_data, display_pstates, 0);
+ dump_cpu_topo_info(output_handler, options.report_data, display_pstates, cpu_topo, 0);
output_handler->pstate_table_footer(options.report_data);
}
if (options.display & WAKEUP_DISPLAY) {
output_handler->wakeup_table_header(options.report_data);
- dump_cpu_topo_info(output_handler, options.report_data, display_wakeup, 1);
+ dump_cpu_topo_info(output_handler, options.report_data, display_wakeup, cpu_topo, 1);
output_handler->wakeup_table_footer(options.report_data);
}
if (options.energy_model_filename)
- calculate_energy_consumption(&options);
+ calculate_energy_consumption(cpu_topo, &options);
output_handler->close_report_file(options.report_data);
}
release_init_pstates(initp);
- release_cpu_topo_cstates();
- release_cpu_topo_info();
+ release_cpu_topo_cstates(cpu_topo);
+ release_cpu_topo_info(cpu_topo);
release_pstate_info(datas->pstates, datas->nrcpus);
release_cstate_info(datas->cstates, datas->nrcpus);
free(datas);