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