diff options
Diffstat (limited to 'tools/power/cpupower/utils/cpupower.c')
-rw-r--r-- | tools/power/cpupower/utils/cpupower.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/tools/power/cpupower/utils/cpupower.c b/tools/power/cpupower/utils/cpupower.c new file mode 100644 index 00000000000..b048e559535 --- /dev/null +++ b/tools/power/cpupower/utils/cpupower.c | |||
@@ -0,0 +1,201 @@ | |||
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 | * Ideas taken over from the perf userspace tool (included in the Linus | ||
7 | * kernel git repo): subcommand builtins and param parsing. | ||
8 | */ | ||
9 | |||
10 | #include <stdio.h> | ||
11 | #include <stdlib.h> | ||
12 | #include <string.h> | ||
13 | #include <unistd.h> | ||
14 | |||
15 | #include "builtin.h" | ||
16 | #include "helpers/helpers.h" | ||
17 | #include "helpers/bitmask.h" | ||
18 | |||
19 | struct cmd_struct { | ||
20 | const char *cmd; | ||
21 | int (*main)(int, const char **); | ||
22 | void (*usage)(void); | ||
23 | int needs_root; | ||
24 | }; | ||
25 | |||
26 | #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) | ||
27 | |||
28 | int cmd_help(int argc, const char **argv); | ||
29 | |||
30 | /* Global cpu_info object available for all binaries | ||
31 | * Info only retrieved from CPU 0 | ||
32 | * | ||
33 | * Values will be zero/unknown on non X86 archs | ||
34 | */ | ||
35 | struct cpupower_cpu_info cpupower_cpu_info; | ||
36 | int run_as_root; | ||
37 | /* Affected cpus chosen by -c/--cpu param */ | ||
38 | struct bitmask *cpus_chosen; | ||
39 | |||
40 | #ifdef DEBUG | ||
41 | int be_verbose; | ||
42 | #endif | ||
43 | |||
44 | static void print_help(void); | ||
45 | |||
46 | static struct cmd_struct commands[] = { | ||
47 | { "frequency-info", cmd_freq_info, freq_info_help, 0 }, | ||
48 | { "frequency-set", cmd_freq_set, freq_set_help, 1 }, | ||
49 | { "idle-info", cmd_idle_info, idle_info_help, 0 }, | ||
50 | { "set", cmd_set, set_help, 1 }, | ||
51 | { "info", cmd_info, info_help, 0 }, | ||
52 | { "monitor", cmd_monitor, monitor_help, 0 }, | ||
53 | { "help", cmd_help, print_help, 0 }, | ||
54 | // { "bench", cmd_bench, NULL, 1 }, | ||
55 | }; | ||
56 | |||
57 | int cmd_help(int argc, const char **argv) | ||
58 | { | ||
59 | unsigned int i; | ||
60 | |||
61 | if (argc > 1) { | ||
62 | for (i = 0; i < ARRAY_SIZE(commands); i++) { | ||
63 | struct cmd_struct *p = commands + i; | ||
64 | if (strcmp(p->cmd, argv[1])) | ||
65 | continue; | ||
66 | if (p->usage) { | ||
67 | p->usage(); | ||
68 | return EXIT_SUCCESS; | ||
69 | } | ||
70 | } | ||
71 | } | ||
72 | print_help(); | ||
73 | if (argc == 1) | ||
74 | return EXIT_SUCCESS; /* cpupower help */ | ||
75 | return EXIT_FAILURE; | ||
76 | } | ||
77 | |||
78 | static void print_help(void) | ||
79 | { | ||
80 | unsigned int i; | ||
81 | |||
82 | #ifdef DEBUG | ||
83 | printf(_("cpupower [ -d ][ -c cpulist ] subcommand [ARGS]\n")); | ||
84 | printf(_(" -d, --debug May increase output (stderr) on some subcommands\n")); | ||
85 | #else | ||
86 | printf(_("cpupower [ -c cpulist ] subcommand [ARGS]\n")); | ||
87 | #endif | ||
88 | printf(_("cpupower --version\n")); | ||
89 | printf(_("Supported subcommands are:\n")); | ||
90 | for (i = 0; i < ARRAY_SIZE(commands); i++) | ||
91 | printf("\t%s\n", commands[i].cmd); | ||
92 | printf(_("\nSome subcommands can make use of the -c cpulist option.\n")); | ||
93 | printf(_("Look at the general cpupower manpage how to use it\n")); | ||
94 | printf(_("and read up the subcommand's manpage whether it is supported.\n")); | ||
95 | printf(_("\nUse cpupower help subcommand for getting help for above subcommands.\n")); | ||
96 | } | ||
97 | |||
98 | static void print_version(void) { | ||
99 | printf(PACKAGE " " VERSION "\n"); | ||
100 | printf(_("Report errors and bugs to %s, please.\n"), PACKAGE_BUGREPORT); | ||
101 | } | ||
102 | |||
103 | static void handle_options(int *argc, const char ***argv) | ||
104 | { | ||
105 | int ret, x, new_argc = 0; | ||
106 | |||
107 | if (*argc < 1) | ||
108 | return; | ||
109 | |||
110 | for (x = 0; x < *argc && ((*argv)[x])[0] == '-'; x++) { | ||
111 | const char *param = (*argv)[x]; | ||
112 | if (!strcmp(param, "-h") || !strcmp(param, "--help")){ | ||
113 | print_help(); | ||
114 | exit(EXIT_SUCCESS); | ||
115 | } else if (!strcmp(param, "-c") || !strcmp(param, "--cpu")){ | ||
116 | if (*argc < 2) { | ||
117 | print_help(); | ||
118 | exit(EXIT_FAILURE); | ||
119 | } | ||
120 | if (!strcmp((*argv)[x+1], "all")) | ||
121 | bitmask_setall(cpus_chosen); | ||
122 | else { | ||
123 | ret = bitmask_parselist( | ||
124 | (*argv)[x+1], cpus_chosen); | ||
125 | if (ret < 0) { | ||
126 | fprintf(stderr, _("Error parsing cpu " | ||
127 | "list\n")); | ||
128 | exit(EXIT_FAILURE); | ||
129 | } | ||
130 | } | ||
131 | x += 1; | ||
132 | /* Cut out param: cpupower -c 1 info -> cpupower info */ | ||
133 | new_argc += 2; | ||
134 | continue; | ||
135 | } else if (!strcmp(param, "-v") || !strcmp(param, "--version")){ | ||
136 | print_version(); | ||
137 | exit(EXIT_SUCCESS); | ||
138 | #ifdef DEBUG | ||
139 | } else if (!strcmp(param, "-d") || !strcmp(param, "--debug")){ | ||
140 | be_verbose = 1; | ||
141 | new_argc ++; | ||
142 | continue; | ||
143 | #endif | ||
144 | } else { | ||
145 | fprintf(stderr, "Unknown option: %s\n", param); | ||
146 | print_help(); | ||
147 | exit(EXIT_FAILURE); | ||
148 | } | ||
149 | } | ||
150 | *argc -= new_argc; | ||
151 | *argv += new_argc; | ||
152 | } | ||
153 | |||
154 | int main(int argc, const char *argv[]) | ||
155 | { | ||
156 | const char *cmd; | ||
157 | unsigned int i, ret; | ||
158 | |||
159 | cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF)); | ||
160 | |||
161 | argc--; | ||
162 | argv += 1; | ||
163 | |||
164 | handle_options(&argc, &argv); | ||
165 | |||
166 | cmd = argv[0]; | ||
167 | |||
168 | if (argc < 1) { | ||
169 | print_help(); | ||
170 | return EXIT_FAILURE; | ||
171 | } | ||
172 | |||
173 | setlocale(LC_ALL, ""); | ||
174 | textdomain (PACKAGE); | ||
175 | |||
176 | /* Turn "perf cmd --help" into "perf help cmd" */ | ||
177 | if (argc > 1 && !strcmp(argv[1], "--help")) { | ||
178 | argv[1] = argv[0]; | ||
179 | argv[0] = cmd = "help"; | ||
180 | } | ||
181 | |||
182 | get_cpu_info(0, &cpupower_cpu_info); | ||
183 | run_as_root = !getuid(); | ||
184 | |||
185 | for (i = 0; i < ARRAY_SIZE(commands); i++) { | ||
186 | struct cmd_struct *p = commands + i; | ||
187 | if (strcmp(p->cmd, cmd)) | ||
188 | continue; | ||
189 | if (!run_as_root && p->needs_root) { | ||
190 | fprintf(stderr, _("Subcommand %s needs root " | ||
191 | "privileges\n"), cmd); | ||
192 | return EXIT_FAILURE; | ||
193 | } | ||
194 | ret = p->main(argc, argv); | ||
195 | if (cpus_chosen) | ||
196 | bitmask_free(cpus_chosen); | ||
197 | return ret; | ||
198 | } | ||
199 | print_help(); | ||
200 | return EXIT_FAILURE; | ||
201 | } | ||