-#define DELTA_WRAP32(new, old) \
- if (new > old) { \
- old = new - old; \
- } else { \
- old = 0x100000000 + new - old; \
- }
-
-static void
-delta_package(struct pkg_data *new, struct pkg_data *old)
-{
- old->pc2 = new->pc2 - old->pc2;
- old->pc3 = new->pc3 - old->pc3;
- old->pc6 = new->pc6 - old->pc6;
- old->pc7 = new->pc7 - old->pc7;
- old->pc8 = new->pc8 - old->pc8;
- old->pc9 = new->pc9 - old->pc9;
- old->pc10 = new->pc10 - old->pc10;
- old->pkg_temp_c = new->pkg_temp_c;
-
- DELTA_WRAP32(new->energy_pkg, old->energy_pkg);
- DELTA_WRAP32(new->energy_cores, old->energy_cores);
- DELTA_WRAP32(new->energy_gfx, old->energy_gfx);
- DELTA_WRAP32(new->energy_dram, old->energy_dram);
- DELTA_WRAP32(new->rapl_pkg_perf_status, old->rapl_pkg_perf_status);
- DELTA_WRAP32(new->rapl_dram_perf_status, old->rapl_dram_perf_status);
-}
-
-static void
-delta_core(struct core_data *new, struct core_data *old)
-{
- old->c3 = new->c3 - old->c3;
- old->c6 = new->c6 - old->c6;
- old->c7 = new->c7 - old->c7;
- old->core_temp_c = new->core_temp_c;
-}
-
-/*
- * old = new - old
- */
-static int __attribute__((warn_unused_result))
-delta_thread(struct thread_data *new, struct thread_data *old,
- struct core_data *core_delta)
-{
- old->tsc = new->tsc - old->tsc;
-
- /* check for TSC < 1 Mcycles over interval */
- if (old->tsc < (1000 * 1000)) {
- WARNING("Insanely slow TSC rate, TSC stops in idle? ");
- WARNING("You can disable all c-states by booting with \"idle=poll\" ");
- WARNING("or just the deep ones with \"processor.max_cstate=1\"");
- return -1;
- }
-
- old->c1 = new->c1 - old->c1;
-
- if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) {
- old->aperf = new->aperf - old->aperf;
- old->mperf = new->mperf - old->mperf;
- } else {
- if (!aperf_mperf_unstable) {
- WARNING(" APERF or MPERF went backwards * ");
- WARNING("* Frequency results do not cover entire interval *");
- WARNING("* fix this by running Linux-2.6.30 or later *");
-
- aperf_mperf_unstable = 1;
- }
- }
-
-
- /*
- * As counter collection is not atomic,
- * it is possible for mperf's non-halted cycles + idle states
- * to exceed TSC's all cycles: show c1 = 0% in that case.
- */
- if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > old->tsc)
- old->c1 = 0;
- else {
- /* normal case, derive c1 */
- old->c1 = old->tsc - old->mperf - core_delta->c3
- - core_delta->c6 - core_delta->c7;
- }
-
- if (old->mperf == 0) {
- WARNING("cpu%d MPERF 0!", old->cpu_id);
- old->mperf = 1; /* divide by 0 protection */
- }
-
- old->smi_count = new->smi_count - old->smi_count;
-
- return 0;
-}
-
-static int __attribute__((warn_unused_result))
-delta_cpu(struct thread_data *t, struct core_data *c,
- struct pkg_data *p, struct thread_data *t2,
- struct core_data *c2, struct pkg_data *p2)
-{
- int ret;
-
- /* calculate core delta only for 1st thread in core */
- if (t->flags & CPU_IS_FIRST_THREAD_IN_CORE)
- delta_core(c, c2);
-
- /* always calculate thread delta */
- ret = delta_thread(t, t2, c2); /* c2 is core delta */
- if (ret != 0)
- return ret;
-
- /* calculate package delta only for 1st core in package */
- if (t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)
- delta_package(p, p2);