1 /* chrt.c - Get/set real-time (scheduling) attributes
2 *
3 * Copyright 2016 The Android Open Source Project
4
5 USE_CHRT(NEWTOY(chrt, "mp#bfiorR[!bfior]", TOYFLAG_USR|TOYFLAG_SBIN))
6
7 config CHRT
8 bool "chrt"
9 default n
10 help
11 usage: chrt [-m] [-p PID] [POLICY PRIO] [COMMAND [ARGS...]]
12
13 Get/set a process' real-time (scheduling) attributes.
14
15 -p Apply to given pid
16 -R Set SCHED_RESET_ON_FORK
17 -m Show min/max priorities available
18
19 Policies:
20 -b SCHED_BATCH -f SCHED_FIFO -i SCHED_IDLE
21 -o SCHED_OTHER -r SCHED_RR
22 */
23
24 #define FOR_chrt
25 #include "toys.h"
26
27 #include <linux/sched.h>
28
GLOBALS(long pid;)29 GLOBALS(
30 long pid;
31 )
32
33 static char *policy_name(int policy) {
34 char *policy_names[] = { "SCHED_OTHER", "SCHED_FIFO", "SCHED_RR",
35 "SCHED_BATCH", "4", "SCHED_IDLE", "SCHED_DEADLINE" };
36
37 return policy < ARRAY_LEN(policy_names) ? policy_names[policy] : "???";
38 }
39
chrt_main(void)40 void chrt_main(void)
41 {
42 int policy = SCHED_RR;
43 struct sched_param p;
44
45 // Show min/maxes?
46 if (toys.optflags&FLAG_m) {
47 for (policy = SCHED_OTHER; policy <= SCHED_IDLE; ++policy)
48 if (policy != 4) // There's an unused hole in the priorities.
49 printf("%s min/max priority\t: %d/%d\n", policy_name(policy),
50 sched_get_priority_min(policy), sched_get_priority_max(policy));
51 return;
52 }
53
54 // If we have a pid but no command or policy, we're just querying.
55 if (TT.pid && !*(toys.optargs+1) &&
56 !(toys.optflags&(FLAG_b|FLAG_f|FLAG_i|FLAG_o|FLAG_r))) {
57 policy = sched_getscheduler(TT.pid);
58 if (policy == -1) perror_exit("sched_getscheduler");
59 policy &= ~SCHED_RESET_ON_FORK;
60 printf("pid %ld's current scheduling policy: %s\n",
61 TT.pid, policy_name(policy));
62
63 if (sched_getparam(TT.pid, &p)) perror_exit("sched_getparam");
64 printf("pid %ld's current scheduling priority: %d\n",
65 TT.pid, p.sched_priority);
66
67 return;
68 }
69
70 // Did we get a meaningful combination of arguments?
71 if (!*toys.optargs) help_exit("missing priority");
72 if (TT.pid && *(toys.optargs+1)) help_exit("-p and command");
73 if (!TT.pid && !*(toys.optargs+1)) help_exit("missing command");
74
75 // Translate into policy and priority.
76 if (toys.optflags&FLAG_b) policy = SCHED_BATCH;
77 else if (toys.optflags&FLAG_f) policy = SCHED_FIFO;
78 else if (toys.optflags&FLAG_i) policy = SCHED_IDLE;
79 else if (toys.optflags&FLAG_o) policy = SCHED_OTHER;
80
81 if (toys.optflags&FLAG_R) policy |= SCHED_RESET_ON_FORK;
82
83 p.sched_priority = atolx_range(*toys.optargs, sched_get_priority_min(policy),
84 sched_get_priority_max(policy));
85
86 if (sched_setscheduler(TT.pid, policy, &p)) perror_exit("sched_setscheduler");
87
88 if (*(toys.optargs+1)) {
89 toys.stacktop = 0;
90 xexec(++toys.optargs);
91 }
92 }
93