libbb: use ARG_MAX for bb_arg_max() only if it's 60k+

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>
This commit is contained in:
Denys Vlasenko 2014-11-26 15:17:59 +01:00
parent 2835a224cd
commit 04c1417602
2 changed files with 6 additions and 3 deletions

View File

@ -731,11 +731,14 @@ extern void *xmalloc_open_read_close(const char *filename, size_t *maxsz_p) FAST
/* Never returns NULL */ /* Never returns NULL */
extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; 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) # 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; unsigned bb_arg_max(void) FAST_FUNC;
#else #else
/* If all else fails */
# define bb_arg_max() ((unsigned)(32 * 1024)) # define bb_arg_max() ((unsigned)(32 * 1024))
#endif #endif
unsigned bb_clk_tck(void) FAST_FUNC; unsigned bb_clk_tck(void) FAST_FUNC;

View File

@ -8,7 +8,7 @@
*/ */
#include "libbb.h" #include "libbb.h"
#if !defined(ARG_MAX) && defined(_SC_ARG_MAX) #if !defined(bb_arg_max)
unsigned FAST_FUNC bb_arg_max(void) unsigned FAST_FUNC bb_arg_max(void)
{ {
return sysconf(_SC_ARG_MAX); return sysconf(_SC_ARG_MAX);