From 44eee20598037c45680c862c05bba054372e130a Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Tue, 23 Nov 2021 16:25:30 -0500 Subject: 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. --- exec.c | 18 +++++++++++------- 1 file 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", -- cgit v1.2.3