From ac1d28ea6bf9c0bd7b41725095a5b41ac8a08121 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 17 Nov 2021 14:33:01 -0500 Subject: exec: Find ARG_MAX with binary search after E2BIG Previously we would shrink the command by one argument at a time until a successful execution. This is okay if the ARG_MAX estimate is just a little bit off, but is terribly slow when it's off by a lot. One situation where it's very far off is when a 32-bit build of bfs launches a 64-bit binary. In this case, bfs thinks the argv pointers are 4 bytes, while they actually take up 8 bytes. The performance is quite bad: $ time ./bfs-64 ~/code/linux -exec echo {} + >/dev/null ./bfs-64 ~/code/linux -exec echo {} + > /dev/null 0.03s user 0.07s system 99% cpu 0.095 total $ time ./bfs-32 ~/code/linux -exec echo {} + >/dev/null ./bfs-32 ~/code/linux -exec echo {} + > /dev/null 0.08s user 10.33s system 100% cpu 10.390 total After this change, performance is much better: $ time ./bfs-32 ~/code/linux -exec echo {} + >/dev/null ./bfs-32 ~/code/linux -exec echo {} + > /dev/null 0.03s user 0.08s system 99% cpu 0.110 total --- exec.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'exec.h') diff --git a/exec.h b/exec.h index 1ba409f..a3e3c71 100644 --- a/exec.h +++ b/exec.h @@ -63,6 +63,8 @@ struct bfs_exec { size_t arg_size; /** Maximum arg_size before E2BIG. */ size_t arg_max; + /** Lower bound for arg_max. */ + size_t arg_min; /** A file descriptor for the working directory, for BFS_EXEC_CHDIR. */ int wd_fd; -- cgit v1.2.3