-#define DELTA_WRAP32(delta, new, old) \
- if (new > old) { \
- delta = new - old; \
- } else { \
- delta = 0x100000000 + new - old; \
- }
-
-static void
-delta_package(struct pkg_data *delta, const struct pkg_data *new, const struct pkg_data *old)
-{
- delta->pc2 = new->pc2 - old->pc2;
- delta->pc3 = new->pc3 - old->pc3;
- delta->pc6 = new->pc6 - old->pc6;
- delta->pc7 = new->pc7 - old->pc7;
- delta->pc8 = new->pc8 - old->pc8;
- delta->pc9 = new->pc9 - old->pc9;
- delta->pc10 = new->pc10 - old->pc10;
- delta->pkg_temp_c = new->pkg_temp_c;
-
- DELTA_WRAP32(delta->energy_pkg, new->energy_pkg, old->energy_pkg);
- DELTA_WRAP32(delta->energy_cores, new->energy_cores, old->energy_cores);
- DELTA_WRAP32(delta->energy_gfx, new->energy_gfx, old->energy_gfx);
- DELTA_WRAP32(delta->energy_dram, new->energy_dram, old->energy_dram);
- DELTA_WRAP32(delta->rapl_pkg_perf_status, new->rapl_pkg_perf_status, old->rapl_pkg_perf_status);
- DELTA_WRAP32(delta->rapl_dram_perf_status, new->rapl_dram_perf_status, old->rapl_dram_perf_status);
-}
-
-static void
-delta_core(struct core_data *delta, const struct core_data *new, const struct core_data *old)
-{
- delta->c3 = new->c3 - old->c3;
- delta->c6 = new->c6 - old->c6;
- delta->c7 = new->c7 - old->c7;
- delta->core_temp_c = new->core_temp_c;
-}
-
-static int __attribute__((warn_unused_result))
-delta_thread(struct thread_data *delta, const struct thread_data *new, const struct thread_data *old,
- const struct core_data *core_delta)
-{
- delta->tsc = new->tsc - old->tsc;
-
- /* check for TSC < 1 Mcycles over interval */
- if (delta->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;
- }
-
- delta->c1 = new->c1 - old->c1;
-
- if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) {
- delta->aperf = new->aperf - old->aperf;
- delta->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 ((delta->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > delta->tsc)
- delta->c1 = 0;
- else {
- /* normal case, derive c1 */
- delta->c1 = delta->tsc - delta->mperf - core_delta->c3
- - core_delta->c6 - core_delta->c7;
- }
-
- if (delta->mperf == 0) {
- WARNING("cpu%d MPERF 0!", old->cpu_id);
- delta->mperf = 1; /* divide by 0 protection */
- }
-
- delta->smi_count = new->smi_count - old->smi_count;
-
- return 0;
-}
-
-static int __attribute__((warn_unused_result))
-delta_cpu(struct thread_data *t_delta, struct core_data *c_delta, struct pkg_data *p_delta,
- const struct thread_data *t_new, const struct core_data *c_new, const struct pkg_data *p_new,
- const struct thread_data *t_old, const struct core_data *c_old, const struct pkg_data *p_old)
-{
- int ret;
-
- /* calculate core delta only for 1st thread in core */
- if (t_new->flags & CPU_IS_FIRST_THREAD_IN_CORE)
- delta_core(c_delta, c_new, c_old);
-
- /* always calculate thread delta */
- ret = delta_thread(t_delta, t_new, t_old, c_delta);
- if (ret != 0)
- return ret;
-
- /* calculate package delta only for 1st core in package */
- if (t_new->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)
- delta_package(p_delta, p_new, p_old);
-
- return 0;
-}