1 /*
2  *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc.
3  *
4  *  Licensed under the terms of the GNU GPL License version 2.
5  *
6  */
7 
8 #ifndef __CPUIDLE_INFO_HW__
9 #define __CPUIDLE_INFO_HW__
10 
11 #include <stdarg.h>
12 #include <time.h>
13 
14 #include "idle_monitor/idle_monitors.h"
15 
16 #define MONITORS_MAX 20
17 #define MONITOR_NAME_LEN 20
18 #define CSTATE_NAME_LEN 5
19 #define CSTATE_DESC_LEN 60
20 
21 int cpu_count;
22 
23 /* Hard to define the right names ...: */
24 enum power_range_e {
25 	RANGE_THREAD,	/* Lowest in topology hierarcy, AMD: core, Intel: thread
26 			   kernel sysfs: cpu */
27 	RANGE_CORE,	/* AMD: unit, Intel: core, kernel_sysfs: core_id */
28 	RANGE_PACKAGE,	/* Package, processor socket */
29 	RANGE_MACHINE,	/* Machine, platform wide */
30 	RANGE_MAX };
31 
32 typedef struct cstate {
33 	int  id;
34 	enum power_range_e range;
35 	char name[CSTATE_NAME_LEN];
36 	char desc[CSTATE_DESC_LEN];
37 
38 	/* either provide a percentage or a general count */
39 	int (*get_count_percent)(unsigned int self_id, double *percent,
40 				 unsigned int cpu);
41 	int (*get_count)(unsigned int self_id, unsigned long long *count,
42 			 unsigned int cpu);
43 } cstate_t;
44 
45 struct cpuidle_monitor {
46 	/* Name must not contain whitespaces */
47 	char name[MONITOR_NAME_LEN];
48 	int name_len;
49 	int hw_states_num;
50 	cstate_t *hw_states;
51 	int (*start) (void);
52 	int (*stop) (void);
53 	struct cpuidle_monitor* (*do_register) (void);
54 	void (*unregister)(void);
55 	unsigned int overflow_s;
56 	int needs_root;
57 };
58 
59 extern long long timespec_diff_us(struct timespec start, struct timespec end);
60 
61 #define print_overflow_err(mes, ov)						\
62 {										\
63 	fprintf(stderr, gettext("Measure took %u seconds, but registers could "	\
64 				"overflow at %u seconds, results "		\
65 				"could be inaccurate\n"), mes, ov);		\
66 }
67 
68 
69 /* Taken over from x86info project sources  -> return 0 on success */
70 #include <sched.h>
71 #include <sys/types.h>
72 #include <unistd.h>
73 static inline int bind_cpu(int cpu)
74 {
75 	cpu_set_t set;
76 
77 	if (sched_getaffinity(getpid(), sizeof(set), &set) == 0) {
78 		CPU_ZERO(&set);
79 		CPU_SET(cpu, &set);
80 		return sched_setaffinity(getpid(), sizeof(set), &set);
81 	}
82 	return 1;
83 }
84 
85 #endif /* __CPUIDLE_INFO_HW__ */
86