Hi there,

This patch tells chrt utility to uses syscall() instead calling
sched_{g,s}etscheduler() that are provided by libc. Some libc,
e.g. musl does not fully implement the scheduler functions.

Below is the bloat-o-meter output and the patch for 1_31_stable
branch.

Kind Regards,
Fryderyk

$ ./scripts/bloat-o-meter busybox_unstripped.1_31_stable
busybox_unstripped.1_31_chrt_patch
function                                             old     new   delta
chrt_main                                            544     586     +42
show_min_max                                         100     116     +16
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/0 up/down: 58/0)               Total: 58 bytes

---
 util-linux/chrt.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 60 insertions(+), 6 deletions(-)

diff --git a/util-linux/chrt.c b/util-linux/chrt.c
index 4dd78dabf..5c25a23a9 100644
--- a/util-linux/chrt.c
+++ b/util-linux/chrt.c
@@ -12,6 +12,20 @@
 //config:      Manipulate real-time attributes of a process.
 //config:      This requires sched_{g,s}etparam support in your libc.

+//config:config FEATURE_CHRT_OWN_SCHED_SYSCALLS
+//config:      bool "Use scheduler syscalls directly"
+//config:      default n
+//config:      depends on CHRT
+//config:      help
+//config:      Some libc libraries (e.g. musl) do not provide 
sched_{g,s}etscheduler
+//config:      and sched_{g,s}etparam syscalls. That pretty much renders the 
chrt
+//config:      utility useless. This feature tells chrt not to rely on libc 
and use
+//config:      syscall function directly.
+//config:
+//config:      If you use a libc that does not have those syscalls say 'y' 
here,
+//config:      otherwise say 'n'.
+//config:
+
 //applet:IF_CHRT(APPLET_NOEXEC(chrt, chrt, BB_DIR_USR_BIN, BB_SUID_DROP, chrt))

 //kbuild:lib-$(CONFIG_CHRT) += chrt.o
@@ -35,6 +49,46 @@

 #include <sched.h>
 #include "libbb.h"
+
+#if ENABLE_FEATURE_CHRT_OWN_SCHED_SYSCALLS
+
+#include <syscall.h>
+
+static inline int bb_sched_setscheduler(int pid, int policy, const
struct sched_param *p)
+{
+       return syscall(SYS_sched_setscheduler, pid, policy, p);
+}
+
+static inline int bb_sched_getscheduler(int pid)
+{
+       return syscall(SYS_sched_getscheduler, pid);
+}
+
+static inline int bb_sched_getparam(int pid, struct sched_param *p)
+{
+       return syscall(SYS_sched_getparam, pid, p);
+}
+
+static inline int bb_sched_get_priority_max(int policy)
+{
+       return syscall(SYS_sched_get_priority_max, policy);
+}
+
+static inline int bb_sched_get_priority_min(int policy)
+{
+       return syscall(SYS_sched_get_priority_min, policy);
+}
+
+#else /* ! ENABLE_FEATURE_CHRT_OWN_SCHED_SYSCALLS */
+
+#define bb_sched_getscheduler     sched_getscheduler
+#define bb_sched_setscheduler     sched_setscheduler
+#define bb_sched_getparam         sched_getparam
+#define bb_sched_get_priority_max sched_get_priority_max
+#define bb_sched_get_priority_min sched_get_priority_min
+
+#endif /* ENABLE_FEATURE_CHRT_OWN_SCHED_SYSCALLS */
+
 #ifndef SCHED_IDLE
 # define SCHED_IDLE 5
 #endif
@@ -60,8 +114,8 @@ static void show_min_max(int pol)
        const char *fmt = "SCHED_%s min/max priority\t: %u/%u\n";
        int max, min;

-       max = sched_get_priority_max(pol);
-       min = sched_get_priority_min(pol);
+       max = bb_sched_get_priority_max(pol);
+       min = bb_sched_get_priority_min(pol);
        if ((max|min) < 0)
                fmt = "SCHED_%s not supported\n";
        printf(fmt, policy_name(pol), min, max);
@@ -132,7 +186,7 @@ int chrt_main(int argc UNUSED_PARAM, char **argv)
        if (opt & OPT_p) {
                int pol;
  print_rt_info:
-               pol = sched_getscheduler(pid);
+               pol = bb_sched_getscheduler(pid);
                if (pol < 0)
                        bb_perror_msg_and_die("can't %cet pid %u's policy", 
'g', (int)pid);
 #ifdef SCHED_RESET_ON_FORK
@@ -149,7 +203,7 @@ int chrt_main(int argc UNUSED_PARAM, char **argv)
                printf("pid %u's %s scheduling policy: SCHED_%s\n",
                        pid, current_new, policy_name(pol)
                );
-               if (sched_getparam(pid, &sp))
+               if (bb_sched_getparam(pid, &sp))
                        bb_perror_msg_and_die("can't get pid %u's attributes", 
(int)pid);
                printf("pid %u's %s scheduling priority: %d\n",
                        (int)pid, current_new, sp.sched_priority
@@ -165,10 +219,10 @@ int chrt_main(int argc UNUSED_PARAM, char **argv)
        }

        sp.sched_priority = xstrtou_range(priority, 0,
-               sched_get_priority_min(policy), sched_get_priority_max(policy)
+               bb_sched_get_priority_min(policy), 
bb_sched_get_priority_max(policy)
        );

-       if (sched_setscheduler(pid, policy, &sp) < 0)
+       if (bb_sched_setscheduler(pid, policy, &sp) < 0)
                bb_perror_msg_and_die("can't %cet pid %u's policy", 's', 
(int)pid);

        if (!argv[0]) /* "-p PRIO PID [...]" */
-- 
2.16.4
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to