xref: /third_party/toybox/toys/other/chrt.c (revision 0f66f451)
10f66f451Sopenharmony_ci/* chrt.c - Get/set real-time (scheduling) attributes
20f66f451Sopenharmony_ci *
30f66f451Sopenharmony_ci * Copyright 2016 The Android Open Source Project
40f66f451Sopenharmony_ci *
50f66f451Sopenharmony_ci * Note: -ibrfo flags sorted to match SCHED positions for highest_bit()
60f66f451Sopenharmony_ci
70f66f451Sopenharmony_ciUSE_CHRT(NEWTOY(chrt, "^mp#<0iRbrfo[!ibrfo]", TOYFLAG_USR|TOYFLAG_BIN))
80f66f451Sopenharmony_ci
90f66f451Sopenharmony_ciconfig CHRT
100f66f451Sopenharmony_ci  bool "chrt"
110f66f451Sopenharmony_ci  default y
120f66f451Sopenharmony_ci  help
130f66f451Sopenharmony_ci    usage: chrt [-Rmofrbi] {-p PID [PRIORITY] | [PRIORITY COMMAND...]}
140f66f451Sopenharmony_ci
150f66f451Sopenharmony_ci    Get/set a process' real-time scheduling policy and priority.
160f66f451Sopenharmony_ci
170f66f451Sopenharmony_ci    -p	Set/query given pid (instead of running COMMAND)
180f66f451Sopenharmony_ci    -R	Set SCHED_RESET_ON_FORK
190f66f451Sopenharmony_ci    -m	Show min/max priorities available
200f66f451Sopenharmony_ci
210f66f451Sopenharmony_ci    Set policy (default -r):
220f66f451Sopenharmony_ci
230f66f451Sopenharmony_ci      -o  SCHED_OTHER    -f  SCHED_FIFO    -r  SCHED_RR
240f66f451Sopenharmony_ci      -b  SCHED_BATCH    -i  SCHED_IDLE
250f66f451Sopenharmony_ci*/
260f66f451Sopenharmony_ci
270f66f451Sopenharmony_ci#define FOR_chrt
280f66f451Sopenharmony_ci#include "toys.h"
290f66f451Sopenharmony_ci
300f66f451Sopenharmony_ciGLOBALS(
310f66f451Sopenharmony_ci  long p;
320f66f451Sopenharmony_ci)
330f66f451Sopenharmony_ci
340f66f451Sopenharmony_ci#ifndef _POSIX_PRIORITY_SCHEDULING
350f66f451Sopenharmony_ci// musl-libc intentionally broke sched_get_priority_min() and friends in
360f66f451Sopenharmony_ci// commit 1e21e78bf7a5 because its maintainer didn't like those Linux
370f66f451Sopenharmony_ci// system calls, so work around it here.
380f66f451Sopenharmony_ci#include <sys/syscall.h>
390f66f451Sopenharmony_ci#define sched_get_priority_min(policy) \
400f66f451Sopenharmony_ci  (int)syscall(SYS_sched_get_priority_min, (int)policy)
410f66f451Sopenharmony_ci#define sched_get_priority_max(policy) \
420f66f451Sopenharmony_ci  (int)syscall(SYS_sched_get_priority_max, (int)policy)
430f66f451Sopenharmony_ci#define sched_getparam(pid, param) \
440f66f451Sopenharmony_ci  syscall(SYS_sched_getparam, (pid_t)pid, (void *)param)
450f66f451Sopenharmony_ci#define sched_getscheduler(pid) \
460f66f451Sopenharmony_ci  syscall(SYS_sched_getscheduler, (pid_t)pid)
470f66f451Sopenharmony_ci#define sched_setscheduler(pid, scheduler, param) \
480f66f451Sopenharmony_ci  syscall(SYS_sched_setscheduler, (pid_t)pid, (int)scheduler, (void *)param)
490f66f451Sopenharmony_ci#endif
500f66f451Sopenharmony_ci
510f66f451Sopenharmony_cichar *polnames[] = {
520f66f451Sopenharmony_ci  "SCHED_OTHER", "SCHED_FIFO", "SCHED_RR", "SCHED_BATCH", 0, "SCHED_IDLE",
530f66f451Sopenharmony_ci  "SCHED_DEADLINE"
540f66f451Sopenharmony_ci};
550f66f451Sopenharmony_ci
560f66f451Sopenharmony_civoid chrt_main(void)
570f66f451Sopenharmony_ci{
580f66f451Sopenharmony_ci  int pol, pri;
590f66f451Sopenharmony_ci
600f66f451Sopenharmony_ci  // Show min/maxes?
610f66f451Sopenharmony_ci  if (toys.optflags&FLAG_m) {
620f66f451Sopenharmony_ci    for (pol = 0; pol<ARRAY_LEN(polnames); pol++) if (polnames[pol])
630f66f451Sopenharmony_ci      printf("%s min/max priority\t: %d/%d\n", polnames[pol],
640f66f451Sopenharmony_ci        sched_get_priority_min(pol), sched_get_priority_max(pol));
650f66f451Sopenharmony_ci
660f66f451Sopenharmony_ci    return;
670f66f451Sopenharmony_ci  }
680f66f451Sopenharmony_ci
690f66f451Sopenharmony_ci  // Query when -p without priority.
700f66f451Sopenharmony_ci  if (toys.optflags==FLAG_p && !*toys.optargs) {
710f66f451Sopenharmony_ci    char *s = "???", *R = "";
720f66f451Sopenharmony_ci
730f66f451Sopenharmony_ci    if (-1==(pol = sched_getscheduler(TT.p))) perror_exit("pid %ld", TT.p);
740f66f451Sopenharmony_ci    if (pol & SCHED_RESET_ON_FORK) R = "|SCHED_RESET_ON_FORK";
750f66f451Sopenharmony_ci    if ((pol &= ~SCHED_RESET_ON_FORK)<ARRAY_LEN(polnames)) s = polnames[pol];
760f66f451Sopenharmony_ci    printf("pid %ld's current scheduling policy: %s%s\n", TT.p, s, R);
770f66f451Sopenharmony_ci
780f66f451Sopenharmony_ci    if (sched_getparam(TT.p, (void *)&pri)) perror_exit("sched_getparam");
790f66f451Sopenharmony_ci    printf("pid %ld's current scheduling priority: %d\n", TT.p, pri);
800f66f451Sopenharmony_ci
810f66f451Sopenharmony_ci    return;
820f66f451Sopenharmony_ci  }
830f66f451Sopenharmony_ci
840f66f451Sopenharmony_ci  if (!*toys.optargs) help_exit("no PRIORITY");
850f66f451Sopenharmony_ci  if (!toys.optargs[1] == !(toys.optflags&FLAG_p))
860f66f451Sopenharmony_ci    help_exit("need 1 of -p or COMMAND");
870f66f451Sopenharmony_ci
880f66f451Sopenharmony_ci  // Set policy and priority
890f66f451Sopenharmony_ci  if (-1==(pol = highest_bit(toys.optflags&0x2f))) pol = SCHED_RR;
900f66f451Sopenharmony_ci  pri = atolx_range(*toys.optargs, sched_get_priority_min(pol),
910f66f451Sopenharmony_ci    sched_get_priority_max(pol));
920f66f451Sopenharmony_ci  if (toys.optflags&FLAG_R) pol |= SCHED_RESET_ON_FORK;
930f66f451Sopenharmony_ci
940f66f451Sopenharmony_ci  if (sched_setscheduler(TT.p, pol, (void *)&pri))
950f66f451Sopenharmony_ci    perror_exit("sched_setscheduler");
960f66f451Sopenharmony_ci
970f66f451Sopenharmony_ci  if (*(toys.optargs+1)) xexec(toys.optargs+1);
980f66f451Sopenharmony_ci}
99