OSDN Git Service

Add chrt to pending.
authorElliott Hughes <enh@google.com>
Wed, 24 Aug 2016 21:50:05 +0000 (14:50 -0700)
committerRob Landley <rob@landley.net>
Thu, 25 Aug 2016 23:32:34 +0000 (18:32 -0500)
Requested by a Google team whose product is based on Android.

toys/pending/chrt.c [new file with mode: 0644]

diff --git a/toys/pending/chrt.c b/toys/pending/chrt.c
new file mode 100644 (file)
index 0000000..0c25f48
--- /dev/null
@@ -0,0 +1,92 @@
+/* chrt.c - Get/set real-time (scheduling) attributes
+ *
+ * Copyright 2016 The Android Open Source Project
+
+USE_CHRT(NEWTOY(chrt, "mp#bfiorR[!bfior]", TOYFLAG_USR|TOYFLAG_SBIN))
+
+config CHRT
+  bool "chrt"
+  default y
+  help
+    usage: chrt [-m] [-p PID] [POLICY PRIO] [COMMAND [ARGS...]]
+
+    Get/set a process' real-time (scheduling) attributes.
+
+    -p Apply to given pid
+    -R Set SCHED_RESET_ON_FORK
+    -m Show min/max priorities available
+
+    Policies:
+      -b  SCHED_BATCH    -f  SCHED_FIFO    -i  SCHED_IDLE
+      -o  SCHED_OTHER    -r  SCHED_RR
+*/
+
+#define FOR_chrt
+#include "toys.h"
+
+#include <linux/sched.h>
+
+GLOBALS(
+  long pid;
+)
+
+static char *policy_name(int policy) {
+  char *policy_names[] = { "SCHED_OTHER", "SCHED_FIFO", "SCHED_RR",
+    "SCHED_BATCH", "4", "SCHED_IDLE", "SCHED_DEADLINE" };
+
+  return policy < ARRAY_LEN(policy_names) ? policy_names[policy] : "???";
+}
+
+void chrt_main(void)
+{
+  int policy = SCHED_RR;
+  struct sched_param p;
+
+  // Show min/maxes?
+  if (toys.optflags&FLAG_m) {
+    for (policy = SCHED_OTHER; policy <= SCHED_IDLE; ++policy)
+      if (policy != 4) // There's an unused hole in the priorities.
+        printf("%s min/max priority\t: %d/%d\n", policy_name(policy),
+               sched_get_priority_min(policy), sched_get_priority_max(policy));
+    return;
+  }
+
+  // If we have a pid but no command or policy, we're just querying.
+  if (TT.pid && !*(toys.optargs+1) &&
+      !(toys.optflags&(FLAG_b|FLAG_f|FLAG_i|FLAG_o|FLAG_r))) {
+    policy = sched_getscheduler(TT.pid);
+    if (policy == -1) perror_exit("sched_getscheduler");
+    policy &= ~SCHED_RESET_ON_FORK;
+    printf("pid %ld's current scheduling policy: %s\n",
+           TT.pid, policy_name(policy));
+
+    if (sched_getparam(TT.pid, &p)) perror_exit("sched_getparam");
+    printf("pid %ld's current scheduling priority: %d\n",
+           TT.pid, p.sched_priority);
+
+    return;
+  }
+
+  // Did we get a meaningful combination of arguments?
+  if (!*toys.optargs) help_exit("missing priority");
+  if (TT.pid && *(toys.optargs+1)) help_exit("-p and command");
+  if (!TT.pid && !*(toys.optargs+1)) help_exit("missing command");
+
+  // Translate into policy and priority.
+  if (toys.optflags&FLAG_b) policy = SCHED_BATCH;
+  else if (toys.optflags&FLAG_f) policy = SCHED_FIFO;
+  else if (toys.optflags&FLAG_i) policy = SCHED_IDLE;
+  else if (toys.optflags&FLAG_o) policy = SCHED_OTHER;
+
+  if (toys.optflags&FLAG_R) policy |= SCHED_RESET_ON_FORK;
+
+  p.sched_priority = atolx_range(*toys.optargs, sched_get_priority_min(policy),
+                                 sched_get_priority_max(policy));
+
+  if (sched_setscheduler(TT.pid, policy, &p)) perror_exit("sched_setscheduler");
+
+  if (*(toys.optargs+1)) {
+    toys.stacktop = 0;
+    xexec(++toys.optargs);
+  }
+}