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