chrt.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * chrt - manipulate real-time attributes of a process
  4. * Copyright (c) 2006-2007 Bernhard Fischer
  5. *
  6. * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  7. */
  8. #include <sched.h>
  9. #include <getopt.h> /* optind */
  10. #include "libbb.h"
  11. #ifndef _POSIX_PRIORITY_SCHEDULING
  12. #warning your system may be foobared
  13. #endif
  14. static const struct {
  15. const int policy;
  16. const char const name[12];
  17. } policies[] = {
  18. {SCHED_OTHER, "SCHED_OTHER"},
  19. {SCHED_FIFO, "SCHED_FIFO"},
  20. {SCHED_RR, "SCHED_RR"}
  21. };
  22. static void show_min_max(int pol)
  23. {
  24. const char *fmt = "%s min/max priority\t: %d/%d\n\0%s not supported?\n";
  25. int max, min;
  26. max = sched_get_priority_max(pol);
  27. min = sched_get_priority_min(pol);
  28. if (max >= 0 && min >= 0)
  29. printf(fmt, policies[pol].name, min, max);
  30. else {
  31. fmt += 29;
  32. printf(fmt, policies[pol].name);
  33. }
  34. }
  35. #define OPT_m (1<<0)
  36. #define OPT_p (1<<1)
  37. #define OPT_r (1<<2)
  38. #define OPT_f (1<<3)
  39. #define OPT_o (1<<4)
  40. int chrt_main(int argc, char** argv);
  41. int chrt_main(int argc, char** argv)
  42. {
  43. pid_t pid = 0;
  44. unsigned opt;
  45. struct sched_param sp;
  46. char *p_opt = NULL, *priority = NULL;
  47. const char *state = "current\0new";
  48. int prio = 0, policy = SCHED_RR;
  49. opt_complementary = "r--fo:f--ro:r--fo"; /* only one policy accepted */
  50. opt = getopt32(argc, argv, "+mp:rfo", &p_opt);
  51. if (opt & OPT_r)
  52. policy = SCHED_RR;
  53. if (opt & OPT_f)
  54. policy = SCHED_FIFO;
  55. if (opt & OPT_o)
  56. policy = SCHED_OTHER;
  57. if (opt & OPT_m) { /* print min/max */
  58. show_min_max(SCHED_FIFO);
  59. show_min_max(SCHED_RR);
  60. show_min_max(SCHED_OTHER);
  61. fflush_stdout_and_exit(EXIT_SUCCESS);
  62. }
  63. if (opt & OPT_p) {
  64. if (argc == optind+1) { /* -p <priority> <pid> */
  65. priority = p_opt;
  66. p_opt = argv[optind];
  67. }
  68. argv += optind; /* me -p <arg> */
  69. pid = xatoul_range(p_opt, 1, ULONG_MAX); /* -p <pid> */
  70. } else {
  71. argv += optind; /* me -p <arg> */
  72. priority = *argv;
  73. }
  74. if (priority) {
  75. /* from the manpage of sched_getscheduler:
  76. [...] sched_priority can have a value
  77. in the range 0 to 99.
  78. [...] SCHED_OTHER or SCHED_BATCH must be assigned
  79. the static priority 0. [...] SCHED_FIFO or
  80. SCHED_RR can have a static priority in the range 1 to 99.
  81. */
  82. prio = xstrtol_range(priority, 0, policy == SCHED_OTHER
  83. ? 0 : 1, 99);
  84. }
  85. if (opt & OPT_p) {
  86. int pol = 0;
  87. print_rt_info:
  88. pol = sched_getscheduler(pid);
  89. if (pol < 0)
  90. bb_perror_msg_and_die("failed to %cet pid %d's policy", 'g', pid);
  91. printf("pid %d's %s scheduling policy: %s\n",
  92. pid, state, policies[pol].name);
  93. if (sched_getparam(pid, &sp))
  94. bb_perror_msg_and_die("failed to get pid %d's attributes", pid);
  95. printf("pid %d's %s scheduling priority: %d\n",
  96. pid, state, sp.sched_priority);
  97. if (!*argv) /* no new prio given or we did print already, done. */
  98. return EXIT_SUCCESS;
  99. }
  100. sp.sched_priority = prio;
  101. if (sched_setscheduler(pid, policy, &sp) < 0)
  102. bb_perror_msg_and_die("failed to %cet pid %d's policy", 's', pid);
  103. if (opt & OPT_p) {
  104. state += 8;
  105. ++argv;
  106. goto print_rt_info;
  107. }
  108. ++argv;
  109. BB_EXECVP(*argv, argv);
  110. bb_perror_msg_and_die("%s", *argv);
  111. }
  112. #undef OPT_p
  113. #undef OPT_r
  114. #undef OPT_f
  115. #undef OPT_o
  116. #undef OPT_m