Home | History | Annotate | Download | only in pending
      1 /* chrt.c - Get/set real-time (scheduling) attributes
      2  *
      3  * Copyright 2016 The Android Open Source Project
      4 
      5 USE_CHRT(NEWTOY(chrt, "mp#bfiorR[!bfior]", TOYFLAG_USR|TOYFLAG_SBIN))
      6 
      7 config CHRT
      8   bool "chrt"
      9   default n
     10   help
     11     usage: chrt [-m] [-p PID] [POLICY PRIO] [COMMAND [ARGS...]]
     12 
     13     Get/set a process' real-time (scheduling) attributes.
     14 
     15     -p	Apply to given pid
     16     -R	Set SCHED_RESET_ON_FORK
     17     -m	Show min/max priorities available
     18 
     19     Policies:
     20       -b  SCHED_BATCH    -f  SCHED_FIFO    -i  SCHED_IDLE
     21       -o  SCHED_OTHER    -r  SCHED_RR
     22 */
     23 
     24 #define FOR_chrt
     25 #include "toys.h"
     26 
     27 #include <linux/sched.h>
     28 
     29 GLOBALS(
     30   long pid;
     31 )
     32 
     33 static char *policy_name(int policy) {
     34   char *policy_names[] = { "SCHED_OTHER", "SCHED_FIFO", "SCHED_RR",
     35     "SCHED_BATCH", "4", "SCHED_IDLE", "SCHED_DEADLINE" };
     36 
     37   return policy < ARRAY_LEN(policy_names) ? policy_names[policy] : "???";
     38 }
     39 
     40 void chrt_main(void)
     41 {
     42   int policy = SCHED_RR;
     43   struct sched_param p;
     44 
     45   // Show min/maxes?
     46   if (toys.optflags&FLAG_m) {
     47     for (policy = SCHED_OTHER; policy <= SCHED_IDLE; ++policy)
     48       if (policy != 4) // There's an unused hole in the priorities.
     49         printf("%s min/max priority\t: %d/%d\n", policy_name(policy),
     50                sched_get_priority_min(policy), sched_get_priority_max(policy));
     51     return;
     52   }
     53 
     54   // If we have a pid but no command or policy, we're just querying.
     55   if (TT.pid && !*(toys.optargs+1) &&
     56       !(toys.optflags&(FLAG_b|FLAG_f|FLAG_i|FLAG_o|FLAG_r))) {
     57     policy = sched_getscheduler(TT.pid);
     58     if (policy == -1) perror_exit("sched_getscheduler");
     59     policy &= ~SCHED_RESET_ON_FORK;
     60     printf("pid %ld's current scheduling policy: %s\n",
     61            TT.pid, policy_name(policy));
     62 
     63     if (sched_getparam(TT.pid, &p)) perror_exit("sched_getparam");
     64     printf("pid %ld's current scheduling priority: %d\n",
     65            TT.pid, p.sched_priority);
     66 
     67     return;
     68   }
     69 
     70   // Did we get a meaningful combination of arguments?
     71   if (!*toys.optargs) help_exit("missing priority");
     72   if (TT.pid && *(toys.optargs+1)) help_exit("-p and command");
     73   if (!TT.pid && !*(toys.optargs+1)) help_exit("missing command");
     74 
     75   // Translate into policy and priority.
     76   if (toys.optflags&FLAG_b) policy = SCHED_BATCH;
     77   else if (toys.optflags&FLAG_f) policy = SCHED_FIFO;
     78   else if (toys.optflags&FLAG_i) policy = SCHED_IDLE;
     79   else if (toys.optflags&FLAG_o) policy = SCHED_OTHER;
     80 
     81   if (toys.optflags&FLAG_R) policy |= SCHED_RESET_ON_FORK;
     82 
     83   p.sched_priority = atolx_range(*toys.optargs, sched_get_priority_min(policy),
     84                                  sched_get_priority_max(policy));
     85 
     86   if (sched_setscheduler(TT.pid, policy, &p)) perror_exit("sched_setscheduler");
     87 
     88   if (*(toys.optargs+1)) {
     89     toys.stacktop = 0;
     90     xexec(++toys.optargs);
     91   }
     92 }
     93