diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2021-11-23 16:25:30 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2021-11-23 16:25:30 -0500 |
commit | 44eee20598037c45680c862c05bba054372e130a (patch) | |
tree | a29d85d28ea6270bcbc312542e2223203866605f /exec.c | |
parent | ac1d28ea6bf9c0bd7b41725095a5b41ac8a08121 (diff) | |
download | bfs-44eee20598037c45680c862c05bba054372e130a.tar.xz |
exec: Add a bit of backoff during ARG_MAX bisection
This reduces the number of E2BIGs we see if binary search reaches the
top of the possible range.
Diffstat (limited to 'exec.c')
-rw-r--r-- | exec.c | 18 |
1 files changed, 11 insertions, 7 deletions
@@ -489,8 +489,17 @@ static void bfs_exec_update_min(struct bfs_exec *execbuf) { static size_t bfs_exec_update_max(struct bfs_exec *execbuf) { bfs_exec_debug(execbuf, "Got E2BIG, shrinking argument list...\n"); - if (execbuf->arg_size < execbuf->arg_max) { - execbuf->arg_max = execbuf->arg_size; + size_t size = execbuf->arg_size; + if (size <= execbuf->arg_min) { + // Lower bound was wrong, restart binary search. + execbuf->arg_min = 0; + } + + // Trim a fraction off the max size to avoid repeated failures near the + // top end of the working range + size -= size/16; + if (size < execbuf->arg_max) { + execbuf->arg_max = size; // Don't let min exceed max if (execbuf->arg_min > execbuf->arg_max) { @@ -498,11 +507,6 @@ static size_t bfs_exec_update_max(struct bfs_exec *execbuf) { } } - if (execbuf->arg_size <= execbuf->arg_min) { - // Lower bound was wrong, restart binary search. - execbuf->arg_min = 0; - } - // Binary search for a more precise bound size_t estimate = bfs_exec_estimate_max(execbuf); bfs_exec_debug(execbuf, "ARG_MAX between [%zu, %zu], trying %zu\n", |