1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36#include <sched.h>
37#include "libbb.h"
38#ifndef SCHED_IDLE
39# define SCHED_IDLE 5
40#endif
41
42static const struct {
43 char name[sizeof("SCHED_OTHER")];
44} policies[] = {
45 { "SCHED_OTHER" },
46 { "SCHED_FIFO" },
47 { "SCHED_RR" },
48 { "SCHED_BATCH" },
49 { "" },
50 { "SCHED_IDLE" },
51
52};
53
54static void show_min_max(int pol)
55{
56 const char *fmt = "%s min/max priority\t: %u/%u\n";
57 int max, min;
58
59 max = sched_get_priority_max(pol);
60 min = sched_get_priority_min(pol);
61 if ((max|min) < 0)
62 fmt = "%s not supported\n";
63 printf(fmt, policies[pol].name, min, max);
64}
65
66#define OPT_m (1<<0)
67#define OPT_p (1<<1)
68#define OPT_r (1<<2)
69#define OPT_f (1<<3)
70#define OPT_o (1<<4)
71#define OPT_b (1<<5)
72#define OPT_i (1<<6)
73
74int chrt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
75int chrt_main(int argc UNUSED_PARAM, char **argv)
76{
77 pid_t pid = 0;
78 unsigned opt;
79 struct sched_param sp;
80 char *pid_str;
81 char *priority = priority;
82 const char *current_new;
83 int policy = SCHED_RR;
84
85 opt = getopt32(argv, "^"
86 "+" "mprfobi"
87 "\0"
88
89 "r--fobi:f--robi:o--rfbi:b--rfoi:i--rfob"
90 );
91 if (opt & OPT_m) {
92 show_min_max(SCHED_OTHER);
93 show_min_max(SCHED_FIFO);
94 show_min_max(SCHED_RR);
95 show_min_max(SCHED_BATCH);
96 show_min_max(SCHED_IDLE);
97 fflush_stdout_and_exit(EXIT_SUCCESS);
98 }
99
100
101 if (opt & OPT_f)
102 policy = SCHED_FIFO;
103 if (opt & OPT_o)
104 policy = SCHED_OTHER;
105 if (opt & OPT_b)
106 policy = SCHED_BATCH;
107 if (opt & OPT_i)
108 policy = SCHED_IDLE;
109
110 argv += optind;
111 if (!argv[0])
112 bb_show_usage();
113 if (opt & OPT_p) {
114 pid_str = *argv++;
115 if (*argv) {
116 priority = pid_str;
117 pid_str = *argv;
118 }
119
120 pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1);
121 } else {
122 priority = *argv++;
123 if (!*argv)
124 bb_show_usage();
125 }
126
127 current_new = "current\0new";
128 if (opt & OPT_p) {
129 int pol;
130 print_rt_info:
131 pol = sched_getscheduler(pid);
132 if (pol < 0)
133 bb_perror_msg_and_die("can't %cet pid %d's policy", 'g', (int)pid);
134 printf("pid %d's %s scheduling policy: %s\n",
135 pid, current_new, policies[pol].name);
136 if (sched_getparam(pid, &sp))
137 bb_perror_msg_and_die("can't get pid %d's attributes", (int)pid);
138 printf("pid %d's %s scheduling priority: %d\n",
139 (int)pid, current_new, sp.sched_priority);
140 if (!*argv) {
141
142
143
144 return EXIT_SUCCESS;
145 }
146 *argv = NULL;
147 current_new += 8;
148 }
149
150 sp.sched_priority = xstrtou_range(priority, 0,
151 sched_get_priority_min(policy), sched_get_priority_max(policy)
152 );
153
154 if (sched_setscheduler(pid, policy, &sp) < 0)
155 bb_perror_msg_and_die("can't %cet pid %d's policy", 's', (int)pid);
156
157 if (!argv[0])
158 goto print_rt_info;
159
160 BB_EXECVP_or_die(argv);
161}
162