cpupower.c 4.7 KB

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