hc
2023-10-25 6c2073b7aa40e29d0eca7d571dd7bc590c7ecaa7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*
 *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc.
 *
 *  Licensed under the terms of the GNU GPL License version 2.
 *
 */
 
#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;
   int needs_root;
};
 
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__ */