libbb: use ARG_MAX for bb_arg_max() only if it's 60k+
authorDenys Vlasenko <vda.linux@googlemail.com>
Wed, 26 Nov 2014 14:17:59 +0000 (15:17 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 26 Nov 2014 14:17:59 +0000 (15:17 +0100)
Sometimes ARG_MAX is small (like 32k) yet sysconf(_SC_ARG_MAX)
is big, and people prefer using the bigger value.

OTOH, with sufficiently large ARG_MAX, further wins from
sysconf(_SC_ARG_MAX) being bigger are exponentially smaller:
you can see 4 times fewer fork+execs when you run find, but
when each execed process already takes a thousand parameters
it's likely execution time is dominated by what that process
does with each parameter.

Thus, with this change ARG_MAX is used if it's sufficiently big,
otherwise sysconf(_SC_ARG_MAX) is used.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
include/libbb.h
libbb/sysconf.c

index cc2bea32d53ff2a348fb41cfaff8389f32fb1549..17a0089d8afbc914507a844281b0d1c637fb779c 100644 (file)
@@ -731,11 +731,14 @@ extern void *xmalloc_open_read_close(const char *filename, size_t *maxsz_p) FAST
 /* Never returns NULL */
 extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC;
 
-#if defined ARG_MAX
+#if defined(ARG_MAX) && (ARG_MAX >= 60*1024 || !defined(_SC_ARG_MAX))
+/* Use _constant_ maximum if: defined && (big enough || no variable one exists) */
 # define bb_arg_max() ((unsigned)ARG_MAX)
-#elif defined _SC_ARG_MAX
+#elif defined(_SC_ARG_MAX)
+/* Else use variable one (a bit more expensive) */
 unsigned bb_arg_max(void) FAST_FUNC;
 #else
+/* If all else fails */
 # define bb_arg_max() ((unsigned)(32 * 1024))
 #endif
 unsigned bb_clk_tck(void) FAST_FUNC;
index 031901980337dc65ad22e9195ffbdd0b19fca987..cfad9cdc08a0aaa4ede4ec6a8b0ad8bab144abe5 100644 (file)
@@ -8,7 +8,7 @@
  */
 #include "libbb.h"
 
-#if !defined(ARG_MAX) && defined(_SC_ARG_MAX)
+#if !defined(bb_arg_max)
 unsigned FAST_FUNC bb_arg_max(void)
 {
        return sysconf(_SC_ARG_MAX);