aboutsummaryrefslogtreecommitdiff
path: root/idlestat.c
diff options
context:
space:
mode:
authorTuukka Tikkanen <tuukka.tikkanen@linaro.org>2014-12-29 10:12:54 +0200
committerTuukka Tikkanen <tuukka.tikkanen@linaro.org>2014-12-29 10:17:02 +0200
commit68f7dbab41a862c3879795ae84a14113b72fc872 (patch)
tree31791142ab0c6d40e333f9ddcc7215b6840b7e87 /idlestat.c
parentb850b0df10ac722da3f299873276001026d99cc7 (diff)
Idlestat: Merge pstates between main trace and baseline trace
As pstates are allocated in the pstate arrays only when seen in traces and each trace has its own private arrays, main trace and baseline may end up having different sets of pstates in their arrays. This patch iterates through the pstate arrays and inserts pstate entries into the arrays so that both traces have the same pstates in same order. This allows easy comparison between the two traces. Signed-off-by: Tuukka Tikkanen <tuukka.tikkanen@linaro.org>
Diffstat (limited to 'idlestat.c')
-rw-r--r--idlestat.c48
1 files changed, 46 insertions, 2 deletions
diff --git a/idlestat.c b/idlestat.c
index cfaa098..aef09a1 100644
--- a/idlestat.c
+++ b/idlestat.c
@@ -701,6 +701,48 @@ void cpu_change_pstate(struct cpuidle_datas *datas, int cpu,
}
}
+/**
+ * merge_pstates - make sure both main trace and baseline have same pstates
+ * @datas: pointer to struct cpuidle_datas for main trace
+ * @baseline: pointer to struct cpuidle_datas for baseline trace
+ *
+ * This function adds "empty" pstate records for frequencies that exist
+ * in main trace but not in baseline trace or vice versa. This makes sure
+ * that the data (with zero hits into state for thusly created entries)
+ * exists in both trace results for all frequencies used by either trace.
+ */
+static void merge_pstates(struct cpuidle_datas *datas,
+ struct cpuidle_datas *baseline)
+{
+ int cpu;
+ int idx;
+ struct cpufreq_pstates *percpu_a, *percpu_b;
+
+ assert(datas && !is_err(datas));
+ assert(baseline && !is_err(baseline));
+
+ for (cpu = 0; cpu < datas->nrcpus; ++cpu) {
+ percpu_a = &(datas->pstates[cpu]);
+ percpu_b = &(baseline->pstates[cpu]);
+
+ for (idx = 0; idx < percpu_a->max && idx < percpu_b->max; ) {
+ if (percpu_a->pstate[idx].freq >
+ percpu_b->pstate[idx].freq) {
+ assert(alloc_pstate(percpu_b,
+ percpu_a->pstate[idx].freq) == idx);
+ continue;
+ }
+ if (percpu_a->pstate[idx].freq <
+ percpu_b->pstate[idx].freq) {
+ assert(alloc_pstate(percpu_a,
+ percpu_b->pstate[idx].freq) == idx);
+ continue;
+ }
+ ++idx;
+ }
+ }
+}
+
static void cpu_pstate_idle(struct cpuidle_datas *datas, int cpu, double time)
{
struct cpufreq_pstates *ps = &(datas->pstates[cpu]);
@@ -1654,10 +1696,12 @@ int main(int argc, char *argv[], char *const envp[])
if (is_err(datas))
return 1;
- if (options.baseline_filename)
+ if (options.baseline_filename) {
baseline = idlestat_load(options.baseline_filename);
- else
+ merge_pstates(datas, baseline);
+ } else {
baseline = NULL;
+ }
if (is_err(baseline))
return 1;