summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2021-11-23 16:25:30 -0500
committerTavian Barnes <tavianator@tavianator.com>2021-11-23 16:25:30 -0500
commit44eee20598037c45680c862c05bba054372e130a (patch)
treea29d85d28ea6270bcbc312542e2223203866605f
parentac1d28ea6bf9c0bd7b41725095a5b41ac8a08121 (diff)
downloadbfs-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.
-rw-r--r--exec.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/exec.c b/exec.c
index 786a709..45233e1 100644
--- a/exec.c
+++ b/exec.c
@@ -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",