]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
chrt: use sched_getattr()
authorKarel Zak <kzak@redhat.com>
Wed, 20 Jan 2016 14:32:30 +0000 (15:32 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 20 Jan 2016 14:32:30 +0000 (15:32 +0100)
schedutils/chrt.c

index e468f4a6d25ed352df6f10b2e649de5418a40987..030be572ddcb9b3f0bca06b8c0b5914408239170 100644 (file)
 # define SCHED_IDLE 5
 #endif
 
+/* flag by sched_getscheduler() */
 #if defined(__linux__) && !defined(SCHED_RESET_ON_FORK)
-#define SCHED_RESET_ON_FORK 0x40000000
+# define SCHED_RESET_ON_FORK 0x40000000
+#endif
+
+/* flag by sched_getattr() */
+#if defined(__linux__) && !defined(SCHED_FLAG_RESET_ON_FORK)
+# define SCHED_FLAG_RESET_ON_FORK 0x01
 #endif
 
 
@@ -96,7 +102,6 @@ static int sched_getattr(pid_t pid, struct sched_attr *attr, unsigned int size,
 # define SCHED_DEADLINE 6
 #endif
 
-
 /* control struct */
 struct chrt_ctl {
        pid_t   pid;
@@ -157,72 +162,104 @@ static void __attribute__((__noreturn__)) show_usage(int rc)
        exit(rc);
 }
 
-static void show_sched_pid_info(struct chrt_ctl *ctl, pid_t pid)
+static const char *get_policy_name(int policy)
 {
-       struct sched_param sp;
-       int policy;
-
-       /* don't display "pid 0" as that is confusing */
-       if (!pid)
-               pid = getpid();
-
-       policy = sched_getscheduler(pid);
-       if (policy == -1)
-               err(EXIT_FAILURE, _("failed to get pid %d's policy"), pid);
-
-       if (ctl->altered)
-               printf(_("pid %d's new scheduling policy: "), pid);
-       else
-               printf(_("pid %d's current scheduling policy: "), pid);
-
        switch (policy) {
        case SCHED_OTHER:
-               printf("SCHED_OTHER\n");
-               break;
+               return "SCHED_OTHER";
        case SCHED_FIFO:
-               printf("SCHED_FIFO\n");
-               break;
-#ifdef SCHED_RESET_ON_FORK
        case SCHED_FIFO | SCHED_RESET_ON_FORK:
-               printf("SCHED_FIFO|SCHED_RESET_ON_FORK\n");
-               break;
-#endif
+               return "SCHED_FIFO";
 #ifdef SCHED_IDLE
        case SCHED_IDLE:
-               printf("SCHED_IDLE\n");
-               break;
+               return "SCHED_IDLE";
 #endif
        case SCHED_RR:
-               printf("SCHED_RR\n");
-               break;
-#ifdef SCHED_RESET_ON_FORK
-       case SCHED_RR | SCHED_RESET_ON_FORK:
-               printf("SCHED_RR|SCHED_RESET_ON_FORK\n");
-               break;
-#endif
+               return "SCHED_RR";
 #ifdef SCHED_BATCH
        case SCHED_BATCH:
-               printf("SCHED_BATCH\n");
-               break;
+       case SCHED_RR | SCHED_RESET_ON_FORK:
+               return "SCHED_BATCH";
 #endif
 #ifdef SCHED_DEADLINE
        case SCHED_DEADLINE:
-               printf("SCHED_DEADLINE\n");
-               break;
+               return "SCHED_DEADLINE";
 #endif
        default:
-               warnx(_("unknown scheduling policy"));
+               break;
        }
 
-       if (sched_getparam(pid, &sp))
-               err(EXIT_FAILURE, _("failed to get pid %d's attributes"), pid);
+       return _("unknown");
+}
+
+static void show_sched_pid_info(struct chrt_ctl *ctl, pid_t pid)
+{
+       int policy, reset_on_fork = 0, prio = 0;
+#ifdef SCHED_DEADLINE
+       uint64_t deadline = 0, runtime = 0, period = 0;
+#endif
+
+       /* don't display "pid 0" as that is confusing */
+       if (!pid)
+               pid = getpid();
+
+#ifdef HAVE_SCHED_SETATTR
+       {
+               struct sched_attr sa;
+
+               if (sched_getattr(pid, &sa, sizeof(sa), 0) != 0)
+                       err(EXIT_FAILURE, _("failed to get pid %d's policy"), pid);
+
+               policy = sa.sched_policy;
+               prio = sa.sched_priority;
+               reset_on_fork = sa.sched_flags & SCHED_FLAG_RESET_ON_FORK;
+               deadline = sa.sched_deadline;
+               runtime = sa.sched_runtime;
+               period = sa.sched_period;
+       }
+#else /* !HAVE_SCHED_SETATTR */
+       {
+               struct sched_param sp;
+
+               policy = sched_getscheduler(pid);
+               if (policy == -1)
+                       err(EXIT_FAILURE, _("failed to get pid %d's policy"), pid);
+
+               if (sched_getparam(pid, &sp) != 0)
+                       err(EXIT_FAILURE, _("failed to get pid %d's attributes"), pid);
+               else
+                       prio = sp.sched_priority;
+# ifdef SCHED_RESET_ON_FORK
+               if (policy == (SCHED_FIFO|SCHED_RESET_ON_FORK) || policy == (SCHED_BATCH|SCHED_RESET_ON_FORK))
+                       reset_on_fork = 1;
+# endif
+       }
+#endif /* !HAVE_SCHED_SETATTR */
 
        if (ctl->altered)
-               printf(_("pid %d's new scheduling priority: %d\n"),
-                      pid, sp.sched_priority);
+               printf(_("pid %d's new scheduling policy: %s"), pid, get_policy_name(policy));
        else
-               printf(_("pid %d's current scheduling priority: %d\n"),
-                      pid, sp.sched_priority);
+               printf(_("pid %d's current scheduling policy: %s"), pid, get_policy_name(policy));
+
+       if (reset_on_fork)
+               printf("|SCHED_RESET_ON_FORK");
+       putchar('\n');
+
+       if (ctl->altered)
+               printf(_("pid %d's new scheduling priority: %d\n"), pid, prio);
+       else
+               printf(_("pid %d's current scheduling priority: %d\n"), pid, prio);
+
+#ifdef SCHED_DEADLINE
+       if (policy == SCHED_DEADLINE) {
+               if (ctl->altered)
+                       printf(_("pid %d's new runtime/deadline/period parameters: %ju/%ju/%ju\n"),
+                                       pid, runtime, deadline, period);
+               else
+                       printf(_("pid %d's current runtime/deadline/period parameters: %ju/%ju/%ju\n"),
+                                       pid, runtime, deadline, period);
+       }
+#endif
 }
 
 
@@ -260,30 +297,17 @@ static void show_min_max(void)
                SCHED_DEADLINE,
 #endif
        };
-       const char *names[] = {
-               "OTHER",
-               "FIFO",
-               "RR",
-#ifdef SCHED_BATCH
-               "BATCH",
-#endif
-#ifdef SCHED_IDLE
-               "IDLE",
-#endif
-#ifdef SCHED_DEADLINE
-               "DEADLINE",
-#endif
-       };
 
        for (i = 0; i < ARRAY_SIZE(policies); i++) {
-               int max = sched_get_priority_max(policies[i]);
-               int min = sched_get_priority_min(policies[i]);
+               int plc = policies[i];
+               int max = sched_get_priority_max(plc);
+               int min = sched_get_priority_min(plc);
 
                if (max >= 0 && min >= 0)
                        printf(_("SCHED_%s min/max priority\t: %d/%d\n"),
-                                       names[i], min, max);
+                                       get_policy_name(plc), min, max);
                else
-                       printf(_("SCHED_%s not supported?\n"), names[i]);
+                       printf(_("SCHED_%s not supported?\n"), get_policy_name(plc));
        }
 }
 
@@ -305,10 +329,11 @@ static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
 {
        /* use main() to check if the setting makes sense */
        struct sched_attr sa = {
+               .size           = sizeof(struct sched_attr),
                .sched_policy   = ctl->policy,
                .sched_priority = ctl->priority,
-               .sched_runtime = ctl->runtime,
-               .sched_period = ctl->period,
+               .sched_runtime  = ctl->runtime,
+               .sched_period   = ctl->period,
                .sched_deadline = ctl->deadline
        };
 # ifdef SCHED_RESET_ON_FORK