/* SPDX-License-Identifier: GPL-2.0-only */ /* * (C) 2010,2011 Thomas Renninger <trenn@suse.de>, Novell Inc. */ #ifndef __CPUIDLE_INFO_HW__ #define __CPUIDLE_INFO_HW__ #include <stdarg.h> #include <time.h> #include "idle_monitor/idle_monitors.h" #define MONITORS_MAX 20 #define MONITOR_NAME_LEN 20 /* CSTATE_NAME_LEN is limited by header field width defined * in cpupower-monitor.c. Header field width is defined to be * sum of percent width and two spaces for padding. */ #ifdef __powerpc__ #define CSTATE_NAME_LEN 7 #else #define CSTATE_NAME_LEN 5 #endif #define CSTATE_DESC_LEN 60 extern int cpu_count; /* Hard to define the right names ...: */ enum power_range_e { RANGE_THREAD, /* Lowest in topology hierarcy, AMD: core, Intel: thread kernel sysfs: cpu */ RANGE_CORE, /* AMD: unit, Intel: core, kernel_sysfs: core_id */ RANGE_PACKAGE, /* Package, processor socket */ RANGE_MACHINE, /* Machine, platform wide */ RANGE_MAX }; typedef struct cstate { int id; enum power_range_e range; char name[CSTATE_NAME_LEN]; char desc[CSTATE_DESC_LEN]; /* either provide a percentage or a general count */ int (*get_count_percent)(unsigned int self_id, double *percent, unsigned int cpu); int (*get_count)(unsigned int self_id, unsigned long long *count, unsigned int cpu); } cstate_t; struct cpuidle_monitor { /* Name must not contain whitespaces */ char name[MONITOR_NAME_LEN]; int name_len; int hw_states_num; cstate_t *hw_states; int (*start) (void); int (*stop) (void); struct cpuidle_monitor* (*do_register) (void); void (*unregister)(void); unsigned int overflow_s; struct { unsigned int needs_root:1; unsigned int per_cpu_schedule:1; } flags; }; extern long long timespec_diff_us(struct timespec start, struct timespec end); #define print_overflow_err(mes, ov) \ { \ fprintf(stderr, gettext("Measure took %u seconds, but registers could " \ "overflow at %u seconds, results " \ "could be inaccurate\n"), mes, ov); \ } /* Taken over from x86info project sources -> return 0 on success */ #include <sched.h> #include <sys/types.h> #include <unistd.h> static inline int bind_cpu(int cpu) { cpu_set_t set; if (sched_getaffinity(getpid(), sizeof(set), &set) == 0) { CPU_ZERO(&set); CPU_SET(cpu, &set); return sched_setaffinity(getpid(), sizeof(set), &set); } return 1; } #endif /* __CPUIDLE_INFO_HW__ */