1 /* vi: set sw=4 ts=4: */
3 * chrt - manipulate real-time attributes of a process
4 * Copyright (c) 2006-2007 Bernhard Reutner-Fischer
6 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
9 //config: bool "chrt (4.7 kb)"
12 //config: Manipulate real-time attributes of a process.
13 //config: This requires sched_{g,s}etparam support in your libc.
15 //applet:IF_CHRT(APPLET_NOEXEC(chrt, chrt, BB_DIR_USR_BIN, BB_SUID_DROP, chrt))
17 //kbuild:lib-$(CONFIG_CHRT) += chrt.o
19 //usage:#define chrt_trivial_usage
20 //usage: "-m | -p [PRIO] PID | [-rfobi] PRIO PROG [ARGS]"
21 //usage:#define chrt_full_usage "\n\n"
22 //usage: "Change scheduling priority and class for a process\n"
23 //usage: "\n -m Show min/max priorities"
24 //usage: "\n -p Operate on PID"
25 //usage: "\n -r Set SCHED_RR class"
26 //usage: "\n -f Set SCHED_FIFO class"
27 //usage: "\n -o Set SCHED_OTHER class"
28 //usage: "\n -b Set SCHED_BATCH class"
29 //usage: "\n -i Set SCHED_IDLE class"
31 //usage:#define chrt_example_usage
32 //usage: "$ chrt -r 4 sleep 900; x=$!\n"
33 //usage: "$ chrt -f -p 3 $x\n"
34 //usage: "You need CAP_SYS_NICE privileges to set scheduling attributes of a process"
42 static const char *policy_name(int pol)
47 "OTHER" "\0" /* 0:SCHED_OTHER */
48 "FIFO" "\0" /* 1:SCHED_FIFO */
49 "RR" "\0" /* 2:SCHED_RR */
50 "BATCH" "\0" /* 3:SCHED_BATCH */
51 "ISO" "\0" /* 4:SCHED_ISO */
52 "IDLE" "\0" /* 5:SCHED_IDLE */
53 "DEADLINE", /* 6:SCHED_DEADLINE */
58 static void show_min_max(int pol)
60 const char *fmt = "SCHED_%s min/max priority\t: %u/%u\n";
63 max = sched_get_priority_max(pol);
64 min = sched_get_priority_min(pol);
66 fmt = "SCHED_%s not supported\n";
67 printf(fmt, policy_name(pol), min, max);
78 int chrt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
79 int chrt_main(int argc UNUSED_PARAM, char **argv)
83 struct sched_param sp;
85 char *priority = priority; /* for compiler */
86 const char *current_new;
87 int policy = SCHED_RR;
89 opt = getopt32(argv, "^"
92 /* only one policy accepted: */
93 "r--fobi:f--robi:o--rfbi:b--rfoi:i--rfob"
95 if (opt & OPT_m) { /* print min/max and exit */
96 show_min_max(SCHED_OTHER);
97 show_min_max(SCHED_FIFO);
98 show_min_max(SCHED_RR);
99 show_min_max(SCHED_BATCH);
100 show_min_max(SCHED_IDLE);
101 fflush_stdout_and_exit(EXIT_SUCCESS);
104 // policy = SCHED_RR; - default, already set
108 policy = SCHED_OTHER;
110 policy = SCHED_BATCH;
119 if (*argv) { /* "-p PRIO PID [...]" */
123 /* else "-p PID", and *argv == NULL */
124 pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1);
131 current_new = "current\0new";
135 pol = sched_getscheduler(pid);
137 bb_perror_msg_and_die("can't %cet pid %u's policy", 'g', (int)pid);
138 #ifdef SCHED_RESET_ON_FORK
139 /* "Since Linux 2.6.32, the SCHED_RESET_ON_FORK flag
140 * can be ORed in policy when calling sched_setscheduler().
141 * As a result of including this flag, children created by
142 * fork(2) do not inherit privileged scheduling policies"
144 * This bit is also returned by sched_getscheduler()!
145 * (TODO: do we want to show it?)
147 pol &= ~SCHED_RESET_ON_FORK;
149 printf("pid %u's %s scheduling policy: SCHED_%s\n",
150 pid, current_new, policy_name(pol)
152 if (sched_getparam(pid, &sp))
153 bb_perror_msg_and_die("can't get pid %u's attributes", (int)pid);
154 printf("pid %u's %s scheduling priority: %d\n",
155 (int)pid, current_new, sp.sched_priority
158 /* Either it was just "-p PID",
159 * or it was "-p PRIO PID" and we came here
160 * for the second time (see goto below) */
167 sp.sched_priority = xstrtou_range(priority, 0,
168 sched_get_priority_min(policy), sched_get_priority_max(policy)
171 if (sched_setscheduler(pid, policy, &sp) < 0)
172 bb_perror_msg_and_die("can't %cet pid %u's policy", 's', (int)pid);
174 if (!argv[0]) /* "-p PRIO PID [...]" */
177 BB_EXECVP_or_die(argv);