diff options
-rw-r--r-- | toys/pending/chrt.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/toys/pending/chrt.c b/toys/pending/chrt.c new file mode 100644 index 00000000..0c25f484 --- /dev/null +++ b/toys/pending/chrt.c @@ -0,0 +1,92 @@ +/* chrt.c - Get/set real-time (scheduling) attributes + * + * Copyright 2016 The Android Open Source Project + +USE_CHRT(NEWTOY(chrt, "mp#bfiorR[!bfior]", TOYFLAG_USR|TOYFLAG_SBIN)) + +config CHRT + bool "chrt" + default y + help + usage: chrt [-m] [-p PID] [POLICY PRIO] [COMMAND [ARGS...]] + + Get/set a process' real-time (scheduling) attributes. + + -p Apply to given pid + -R Set SCHED_RESET_ON_FORK + -m Show min/max priorities available + + Policies: + -b SCHED_BATCH -f SCHED_FIFO -i SCHED_IDLE + -o SCHED_OTHER -r SCHED_RR +*/ + +#define FOR_chrt +#include "toys.h" + +#include <linux/sched.h> + +GLOBALS( + long pid; +) + +static char *policy_name(int policy) { + char *policy_names[] = { "SCHED_OTHER", "SCHED_FIFO", "SCHED_RR", + "SCHED_BATCH", "4", "SCHED_IDLE", "SCHED_DEADLINE" }; + + return policy < ARRAY_LEN(policy_names) ? policy_names[policy] : "???"; +} + +void chrt_main(void) +{ + int policy = SCHED_RR; + struct sched_param p; + + // Show min/maxes? + if (toys.optflags&FLAG_m) { + for (policy = SCHED_OTHER; policy <= SCHED_IDLE; ++policy) + if (policy != 4) // There's an unused hole in the priorities. + printf("%s min/max priority\t: %d/%d\n", policy_name(policy), + sched_get_priority_min(policy), sched_get_priority_max(policy)); + return; + } + + // If we have a pid but no command or policy, we're just querying. + if (TT.pid && !*(toys.optargs+1) && + !(toys.optflags&(FLAG_b|FLAG_f|FLAG_i|FLAG_o|FLAG_r))) { + policy = sched_getscheduler(TT.pid); + if (policy == -1) perror_exit("sched_getscheduler"); + policy &= ~SCHED_RESET_ON_FORK; + printf("pid %ld's current scheduling policy: %s\n", + TT.pid, policy_name(policy)); + + if (sched_getparam(TT.pid, &p)) perror_exit("sched_getparam"); + printf("pid %ld's current scheduling priority: %d\n", + TT.pid, p.sched_priority); + + return; + } + + // Did we get a meaningful combination of arguments? + if (!*toys.optargs) help_exit("missing priority"); + if (TT.pid && *(toys.optargs+1)) help_exit("-p and command"); + if (!TT.pid && !*(toys.optargs+1)) help_exit("missing command"); + + // Translate into policy and priority. + if (toys.optflags&FLAG_b) policy = SCHED_BATCH; + else if (toys.optflags&FLAG_f) policy = SCHED_FIFO; + else if (toys.optflags&FLAG_i) policy = SCHED_IDLE; + else if (toys.optflags&FLAG_o) policy = SCHED_OTHER; + + if (toys.optflags&FLAG_R) policy |= SCHED_RESET_ON_FORK; + + p.sched_priority = atolx_range(*toys.optargs, sched_get_priority_min(policy), + sched_get_priority_max(policy)); + + if (sched_setscheduler(TT.pid, policy, &p)) perror_exit("sched_setscheduler"); + + if (*(toys.optargs+1)) { + toys.stacktop = 0; + xexec(++toys.optargs); + } +} |