cpupower.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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. printf(PACKAGE " " VERSION "\n");
  86. printf(_("Report errors and bugs to %s, please.\n"), PACKAGE_BUGREPORT);
  87. }
  88. static void handle_options(int *argc, const char ***argv)
  89. {
  90. int ret, x, new_argc = 0;
  91. if (*argc < 1)
  92. return;
  93. for (x = 0; x < *argc && ((*argv)[x])[0] == '-'; x++) {
  94. const char *param = (*argv)[x];
  95. if (!strcmp(param, "-h") || !strcmp(param, "--help")){
  96. print_help();
  97. exit(EXIT_SUCCESS);
  98. } else if (!strcmp(param, "-c") || !strcmp(param, "--cpu")){
  99. if (*argc < 2) {
  100. print_help();
  101. exit(EXIT_FAILURE);
  102. }
  103. if (!strcmp((*argv)[x+1], "all"))
  104. bitmask_setall(cpus_chosen);
  105. else {
  106. ret = bitmask_parselist(
  107. (*argv)[x+1], cpus_chosen);
  108. if (ret < 0) {
  109. fprintf(stderr, _("Error parsing cpu "
  110. "list\n"));
  111. exit(EXIT_FAILURE);
  112. }
  113. }
  114. x += 1;
  115. /* Cut out param: cpupower -c 1 info -> cpupower info */
  116. new_argc += 2;
  117. continue;
  118. } else if (!strcmp(param, "-v") || !strcmp(param, "--version")){
  119. print_version();
  120. exit(EXIT_SUCCESS);
  121. #ifdef DEBUG
  122. } else if (!strcmp(param, "-d") || !strcmp(param, "--debug")){
  123. be_verbose = 1;
  124. new_argc ++;
  125. continue;
  126. #endif
  127. } else {
  128. fprintf(stderr, "Unknown option: %s\n", param);
  129. print_help();
  130. exit(EXIT_FAILURE);
  131. }
  132. }
  133. *argc -= new_argc;
  134. *argv += new_argc;
  135. }
  136. int main(int argc, const char *argv[])
  137. {
  138. const char *cmd;
  139. unsigned int i, ret;
  140. cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
  141. argc--;
  142. argv += 1;
  143. handle_options(&argc, &argv);
  144. cmd = argv[0];
  145. if (argc < 1) {
  146. print_help();
  147. return EXIT_FAILURE;
  148. }
  149. setlocale(LC_ALL, "");
  150. textdomain (PACKAGE);
  151. /* Turn "perf cmd --help" into "perf help cmd" */
  152. if (argc > 1 && !strcmp(argv[1], "--help")) {
  153. argv[1] = argv[0];
  154. argv[0] = cmd = "help";
  155. }
  156. get_cpu_info(0, &cpupower_cpu_info);
  157. run_as_root = !getuid();
  158. for (i = 0; i < ARRAY_SIZE(commands); i++) {
  159. struct cmd_struct *p = commands + i;
  160. if (strcmp(p->cmd, cmd))
  161. continue;
  162. if (!run_as_root && p->needs_root) {
  163. fprintf(stderr, _("Subcommand %s needs root "
  164. "privileges\n"), cmd);
  165. return EXIT_FAILURE;
  166. }
  167. ret = p->main(argc, argv);
  168. if (cpus_chosen)
  169. bitmask_free(cpus_chosen);
  170. return ret;
  171. }
  172. print_help();
  173. return EXIT_FAILURE;
  174. }