[PATCH]: util-linux/chrt: use syscall() directly for shed_* functions

Fryderyk Wrobel frd1996 at gmail.com
Mon Jul 15 13:29:14 UTC 2019


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


More information about the busybox mailing list