1*cf5a6c84SAndroid Build Coastguard Worker /* chrt.c - Get/set real-time (scheduling) attributes
2*cf5a6c84SAndroid Build Coastguard Worker *
3*cf5a6c84SAndroid Build Coastguard Worker * Copyright 2016 The Android Open Source Project
4*cf5a6c84SAndroid Build Coastguard Worker *
5*cf5a6c84SAndroid Build Coastguard Worker * Note: -ibrfo flags sorted to match SCHED positions for highest_bit()
6*cf5a6c84SAndroid Build Coastguard Worker
7*cf5a6c84SAndroid Build Coastguard Worker USE_CHRT(NEWTOY(chrt, "^mp#<0iRbrfo[!ibrfo]", TOYFLAG_USR|TOYFLAG_BIN))
8*cf5a6c84SAndroid Build Coastguard Worker
9*cf5a6c84SAndroid Build Coastguard Worker config CHRT
10*cf5a6c84SAndroid Build Coastguard Worker bool "chrt"
11*cf5a6c84SAndroid Build Coastguard Worker default y
12*cf5a6c84SAndroid Build Coastguard Worker help
13*cf5a6c84SAndroid Build Coastguard Worker usage: chrt [-Rmofrbi] {-p PID [PRIORITY] | [PRIORITY COMMAND...]}
14*cf5a6c84SAndroid Build Coastguard Worker
15*cf5a6c84SAndroid Build Coastguard Worker Get/set a process' real-time scheduling policy and priority.
16*cf5a6c84SAndroid Build Coastguard Worker
17*cf5a6c84SAndroid Build Coastguard Worker -p Set/query given pid (instead of running COMMAND)
18*cf5a6c84SAndroid Build Coastguard Worker -R Set SCHED_RESET_ON_FORK
19*cf5a6c84SAndroid Build Coastguard Worker -m Show min/max priorities available
20*cf5a6c84SAndroid Build Coastguard Worker
21*cf5a6c84SAndroid Build Coastguard Worker Set policy (default -r):
22*cf5a6c84SAndroid Build Coastguard Worker
23*cf5a6c84SAndroid Build Coastguard Worker -o SCHED_OTHER -f SCHED_FIFO -r SCHED_RR
24*cf5a6c84SAndroid Build Coastguard Worker -b SCHED_BATCH -i SCHED_IDLE
25*cf5a6c84SAndroid Build Coastguard Worker */
26*cf5a6c84SAndroid Build Coastguard Worker
27*cf5a6c84SAndroid Build Coastguard Worker #define FOR_chrt
28*cf5a6c84SAndroid Build Coastguard Worker #include "toys.h"
29*cf5a6c84SAndroid Build Coastguard Worker
30*cf5a6c84SAndroid Build Coastguard Worker GLOBALS(
31*cf5a6c84SAndroid Build Coastguard Worker long p;
32*cf5a6c84SAndroid Build Coastguard Worker )
33*cf5a6c84SAndroid Build Coastguard Worker
34*cf5a6c84SAndroid Build Coastguard Worker #ifndef _POSIX_PRIORITY_SCHEDULING
35*cf5a6c84SAndroid Build Coastguard Worker // musl-libc intentionally broke sched_get_priority_min() and friends in
36*cf5a6c84SAndroid Build Coastguard Worker // commit 1e21e78bf7a5 because its maintainer didn't like those Linux
37*cf5a6c84SAndroid Build Coastguard Worker // system calls, so work around it here.
38*cf5a6c84SAndroid Build Coastguard Worker #define sched_get_priority_min(policy) \
39*cf5a6c84SAndroid Build Coastguard Worker (int)syscall(SYS_sched_get_priority_min, (int)policy)
40*cf5a6c84SAndroid Build Coastguard Worker #define sched_get_priority_max(policy) \
41*cf5a6c84SAndroid Build Coastguard Worker (int)syscall(SYS_sched_get_priority_max, (int)policy)
42*cf5a6c84SAndroid Build Coastguard Worker #define sched_getparam(pid, param) \
43*cf5a6c84SAndroid Build Coastguard Worker syscall(SYS_sched_getparam, (pid_t)pid, (void *)param)
44*cf5a6c84SAndroid Build Coastguard Worker #define sched_getscheduler(pid) \
45*cf5a6c84SAndroid Build Coastguard Worker syscall(SYS_sched_getscheduler, (pid_t)pid)
46*cf5a6c84SAndroid Build Coastguard Worker #define sched_setscheduler(pid, scheduler, param) \
47*cf5a6c84SAndroid Build Coastguard Worker syscall(SYS_sched_setscheduler, (pid_t)pid, (int)scheduler, (void *)param)
48*cf5a6c84SAndroid Build Coastguard Worker #endif
49*cf5a6c84SAndroid Build Coastguard Worker
50*cf5a6c84SAndroid Build Coastguard Worker static char *polnames[] = {
51*cf5a6c84SAndroid Build Coastguard Worker "SCHED_OTHER", "SCHED_FIFO", "SCHED_RR", "SCHED_BATCH", 0, "SCHED_IDLE",
52*cf5a6c84SAndroid Build Coastguard Worker "SCHED_DEADLINE"
53*cf5a6c84SAndroid Build Coastguard Worker };
54*cf5a6c84SAndroid Build Coastguard Worker
chrt_main(void)55*cf5a6c84SAndroid Build Coastguard Worker void chrt_main(void)
56*cf5a6c84SAndroid Build Coastguard Worker {
57*cf5a6c84SAndroid Build Coastguard Worker int pol, pri;
58*cf5a6c84SAndroid Build Coastguard Worker
59*cf5a6c84SAndroid Build Coastguard Worker // Show min/maxes?
60*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(m)) {
61*cf5a6c84SAndroid Build Coastguard Worker for (pol = 0; pol<ARRAY_LEN(polnames); pol++) if (polnames[pol])
62*cf5a6c84SAndroid Build Coastguard Worker printf("%s min/max priority\t: %d/%d\n", polnames[pol],
63*cf5a6c84SAndroid Build Coastguard Worker sched_get_priority_min(pol), sched_get_priority_max(pol));
64*cf5a6c84SAndroid Build Coastguard Worker
65*cf5a6c84SAndroid Build Coastguard Worker return;
66*cf5a6c84SAndroid Build Coastguard Worker }
67*cf5a6c84SAndroid Build Coastguard Worker
68*cf5a6c84SAndroid Build Coastguard Worker // Query when -p without priority.
69*cf5a6c84SAndroid Build Coastguard Worker if (toys.optflags==FLAG_p && !*toys.optargs) {
70*cf5a6c84SAndroid Build Coastguard Worker char *s = "???", *R = "";
71*cf5a6c84SAndroid Build Coastguard Worker
72*cf5a6c84SAndroid Build Coastguard Worker if (-1==(pol = sched_getscheduler(TT.p))) perror_exit("pid %ld", TT.p);
73*cf5a6c84SAndroid Build Coastguard Worker if (pol & SCHED_RESET_ON_FORK) R = "|SCHED_RESET_ON_FORK";
74*cf5a6c84SAndroid Build Coastguard Worker if ((pol &= ~SCHED_RESET_ON_FORK)<ARRAY_LEN(polnames)) s = polnames[pol];
75*cf5a6c84SAndroid Build Coastguard Worker printf("pid %ld's current scheduling policy: %s%s\n", TT.p, s, R);
76*cf5a6c84SAndroid Build Coastguard Worker
77*cf5a6c84SAndroid Build Coastguard Worker if (sched_getparam(TT.p, (void *)&pri)) perror_exit("sched_getparam");
78*cf5a6c84SAndroid Build Coastguard Worker printf("pid %ld's current scheduling priority: %d\n", TT.p, pri);
79*cf5a6c84SAndroid Build Coastguard Worker
80*cf5a6c84SAndroid Build Coastguard Worker return;
81*cf5a6c84SAndroid Build Coastguard Worker }
82*cf5a6c84SAndroid Build Coastguard Worker
83*cf5a6c84SAndroid Build Coastguard Worker if (!*toys.optargs) help_exit("no PRIORITY");
84*cf5a6c84SAndroid Build Coastguard Worker if (!toys.optargs[1] == !FLAG(p)) help_exit("need 1 of -p or COMMAND");
85*cf5a6c84SAndroid Build Coastguard Worker
86*cf5a6c84SAndroid Build Coastguard Worker // Set policy and priority
87*cf5a6c84SAndroid Build Coastguard Worker if (-1==(pol = highest_bit(toys.optflags&(FLAG_p-1)))) pol = SCHED_RR;
88*cf5a6c84SAndroid Build Coastguard Worker pri = atolx_range(*toys.optargs, sched_get_priority_min(pol),
89*cf5a6c84SAndroid Build Coastguard Worker sched_get_priority_max(pol));
90*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(R)) pol |= SCHED_RESET_ON_FORK;
91*cf5a6c84SAndroid Build Coastguard Worker
92*cf5a6c84SAndroid Build Coastguard Worker if (sched_setscheduler(TT.p, pol, (void *)&pri))
93*cf5a6c84SAndroid Build Coastguard Worker perror_exit("sched_setscheduler");
94*cf5a6c84SAndroid Build Coastguard Worker
95*cf5a6c84SAndroid Build Coastguard Worker if (*(toys.optargs+1)) xexec(toys.optargs+1);
96*cf5a6c84SAndroid Build Coastguard Worker }
97