Home | History | Annotate | Download | only in other
      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 
      7 USE_CHRT(NEWTOY(chrt, "^mp#<0iRbrfo[!ibrfo]", TOYFLAG_USR|TOYFLAG_SBIN))
      8 
      9 config 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 
     30 GLOBALS(
     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 
     38 char *polnames[] = {
     39   "SCHED_OTHER", "SCHED_FIFO", "SCHED_RR", "SCHED_BATCH", 0, "SCHED_IDLE",
     40   "SCHED_DEADLINE"
     41 };
     42 
     43 void 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