git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v3 04/15] run-command API: make "n" parameter a "size_t"

From
PWPhillip Wood <phillip.wood123@gmail.com>
Date
Oct 14, 2022, 09:30 UTC
Message-ID
<a7463bc5-9a92-8f0f-c0ee-e72fbbeedc09@dunelm.org.uk>
In-Reply-To
<patch-v3-04.15-58018a79b2f-20221012T205712Z-avarab@gmail.com>
On 12/10/2022 22:02, Ævar Arnfjörð Bjarmason wrote:
Show 19 quoted lines
> Make the "n" variable added in c553c72eed6 (run-command: add an
> asynchronous parallel child processor, 2015-12-15) a "size_t". As
> we'll see in a subsequent commit we do pass "0" here, but never "jobs
> < 0".
> 
> We could have made it an "unsigned int", but as we're having to change
> this let's not leave another case in the codebase where a size_t and
> "unsigned int" size differ on some platforms. In this case it's likely
> to never matter, but it's easier to not need to worry about it.
> 
> After this and preceding changes:
> 
> 	make run-command.o DEVOPTS=extra-all CFLAGS=-Wno-unused-parameter
> 
> Only has one (and new) -Wsigned-compare warning relevant to a
> comparison about our "n" or "{nr,max}_processes": About using our
> "n" (size_t) in the same expression as online_cpus() (int). A
> subsequent commit will adjust & deal with online_cpus() and that
> warning.

I've changed my mind a bit on this patch. Previously I thought it was just unnecessary, now I think it is actually going in the wrong direction. You have not changed any of the call sites which are all still passing an int, so you are introducing a bunch of signed->unsigned conversions. Before this patch we could have caught a negative value of n with an assertion. After this patch a negative value passed will become a large positive value (you have audited the current callers but that does not protect us from future mistakes). To be clear I think dropping this patch is the right way forward, not changing all the callers. Using an int for the number of processes seems perfectly reasonable and matches what all the callers are using.

Best Wishes
Phillip
Show 209 quoted lines
> The only users of the "n" parameter are:
> 
>   * builtin/fetch.c: defaults to 1, reads from the "fetch.parallel"
>     config. As seen in the code that parses the config added in
>     d54dea77dba (fetch: let --jobs=<n> parallelize --multiple, too,
>     2019-10-05) will die if the git_config_int() return value is < 0.
> 
>     It will however pass us n = 0, as we'll see in a subsequent commit.
> 
>   * submodule.c: defaults to 1, reads from "submodule.fetchJobs"
>     config. Read via code originally added in a028a1930c6 (fetching
>     submodules: respect `submodule.fetchJobs` config option, 2016-02-29).
> 
>     It now piggy-backs on the the submodule.fetchJobs code and
>     validation added in f20e7c1ea24 (submodule: remove
>     submodule.fetchjobs from submodule-config parsing, 2017-08-02).
> 
>     Like builtin/fetch.c it will die if the git_config_int() return
>     value is < 0, but like builtin/fetch.c it will pass us n = 0.
> 
>   * builtin/submodule--helper.c: defaults to 1. Read via code
>     originally added in 2335b870fa7 (submodule update: expose parallelism
>     to the user, 2016-02-29).
> 
>     Since f20e7c1ea24 (submodule: remove submodule.fetchjobs from
>     submodule-config parsing, 2017-08-02) it shares a config parser and
>     semantics with the submodule.c caller.
> 
>   * hook.c: hardcoded to 1, see 96e7225b310 (hook: add 'run'
>     subcommand, 2021-12-22).
> 
>   * t/helper/test-run-command.c: can be -1 after parsing the arguments,
>     but will then be overridden to online_cpus() before passing it to
>     this API. See be5d88e1128 (test-tool run-command: learn to run (parts
>     of) the testsuite, 2019-10-04).
> 
> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
> ---
>   run-command.c | 42 ++++++++++++++++++------------------------
>   run-command.h |  4 ++--
>   2 files changed, 20 insertions(+), 26 deletions(-)
> 
> diff --git a/run-command.c b/run-command.c
> index 642e6b6e057..14a6e38e804 100644
> --- a/run-command.c
> +++ b/run-command.c
> @@ -1500,8 +1500,8 @@ int run_processes_parallel_ungroup;
>   struct parallel_processes {
>   	void *data;
>   
> -	int max_processes;
> -	int nr_processes;
> +	size_t max_processes;
> +	size_t nr_processes;
>   
>   	get_next_task_fn get_next_task;
>   	start_failure_fn start_failure;
> @@ -1522,7 +1522,7 @@ struct parallel_processes {
>   	unsigned shutdown : 1;
>   	unsigned ungroup : 1;
>   
> -	int output_owner;
> +	size_t output_owner;
>   	struct strbuf buffered_output; /* of finished children */
>   };
>   
> @@ -1543,9 +1543,7 @@ static int default_task_finished(int result,
>   
>   static void kill_children(struct parallel_processes *pp, int signo)
>   {
> -	int i, n = pp->max_processes;
> -
> -	for (i = 0; i < n; i++)
> +	for (size_t i = 0; i < pp->max_processes; i++)
>   		if (pp->children[i].state == GIT_CP_WORKING)
>   			kill(pp->children[i].process.pid, signo);
>   }
> @@ -1560,20 +1558,19 @@ static void handle_children_on_signal(int signo)
>   }
>   
>   static void pp_init(struct parallel_processes *pp,
> -		    int n,
> +		    size_t n,
>   		    get_next_task_fn get_next_task,
>   		    start_failure_fn start_failure,
>   		    task_finished_fn task_finished,
>   		    void *data, int ungroup)
>   {
> -	int i;
> -
>   	if (n < 1)
>   		n = online_cpus();
>   
>   	pp->max_processes = n;
>   
> -	trace_printf("run_processes_parallel: preparing to run up to %d tasks", n);
> +	trace_printf("run_processes_parallel: preparing to run up to %"PRIuMAX" tasks",
> +		     (uintmax_t)n);
>   
>   	pp->data = data;
>   	if (!get_next_task)
> @@ -1594,7 +1591,7 @@ static void pp_init(struct parallel_processes *pp,
>   		CALLOC_ARRAY(pp->pfd, n);
>   	strbuf_init(&pp->buffered_output, 0);
>   
> -	for (i = 0; i < n; i++) {
> +	for (size_t i = 0; i < n; i++) {
>   		strbuf_init(&pp->children[i].err, 0);
>   		child_process_init(&pp->children[i].process);
>   		if (pp->pfd) {
> @@ -1609,10 +1606,8 @@ static void pp_init(struct parallel_processes *pp,
>   
>   static void pp_cleanup(struct parallel_processes *pp)
>   {
> -	int i;
> -
>   	trace_printf("run_processes_parallel: done");
> -	for (i = 0; i < pp->max_processes; i++) {
> +	for (size_t i = 0; i < pp->max_processes; i++) {
>   		strbuf_release(&pp->children[i].err);
>   		child_process_clear(&pp->children[i].process);
>   	}
> @@ -1639,7 +1634,8 @@ static void pp_cleanup(struct parallel_processes *pp)
>    */
>   static int pp_start_one(struct parallel_processes *pp)
>   {
> -	int i, code;
> +	size_t i;
> +	int code;
>   
>   	for (i = 0; i < pp->max_processes; i++)
>   		if (pp->children[i].state == GIT_CP_FREE)
> @@ -1697,7 +1693,7 @@ static void pp_buffer_stderr(struct parallel_processes *pp, int output_timeout)
>   	}
>   
>   	/* Buffer output from all pipes. */
> -	for (i = 0; i < pp->max_processes; i++) {
> +	for (size_t i = 0; i < pp->max_processes; i++) {
>   		if (pp->children[i].state == GIT_CP_WORKING &&
>   		    pp->pfd[i].revents & (POLLIN | POLLHUP)) {
>   			int n = strbuf_read_once(&pp->children[i].err,
> @@ -1714,7 +1710,7 @@ static void pp_buffer_stderr(struct parallel_processes *pp, int output_timeout)
>   
>   static void pp_output(struct parallel_processes *pp)
>   {
> -	int i = pp->output_owner;
> +	size_t i = pp->output_owner;
>   
>   	if (pp->children[i].state == GIT_CP_WORKING &&
>   	    pp->children[i].err.len) {
> @@ -1725,8 +1721,8 @@ static void pp_output(struct parallel_processes *pp)
>   
>   static int pp_collect_finished(struct parallel_processes *pp)
>   {
> -	int i, code;
> -	int n = pp->max_processes;
> +	int code;
> +	size_t i, n = pp->max_processes;
>   	int result = 0;
>   
>   	while (pp->nr_processes > 0) {
> @@ -1783,7 +1779,7 @@ static int pp_collect_finished(struct parallel_processes *pp)
>   	return result;
>   }
>   
> -void run_processes_parallel(int n,
> +void run_processes_parallel(size_t n,
>   			    get_next_task_fn get_next_task,
>   			    start_failure_fn start_failure,
>   			    task_finished_fn task_finished,
> @@ -1817,9 +1813,7 @@ void run_processes_parallel(int n,
>   		if (!pp.nr_processes)
>   			break;
>   		if (ungroup) {
> -			int i;
> -
> -			for (i = 0; i < pp.max_processes; i++)
> +			for (size_t i = 0; i < pp.max_processes; i++)
>   				pp.children[i].state = GIT_CP_WAIT_CLEANUP;
>   		} else {
>   			pp_buffer_stderr(&pp, output_timeout);
> @@ -1836,7 +1830,7 @@ void run_processes_parallel(int n,
>   	pp_cleanup(&pp);
>   }
>   
> -void run_processes_parallel_tr2(int n, get_next_task_fn get_next_task,
> +void run_processes_parallel_tr2(size_t n, get_next_task_fn get_next_task,
>   				start_failure_fn start_failure,
>   				task_finished_fn task_finished, void *pp_cb,
>   				const char *tr2_category, const char *tr2_label)
> diff --git a/run-command.h b/run-command.h
> index e76a1b6b5b3..6f7604e1146 100644
> --- a/run-command.h
> +++ b/run-command.h
> @@ -485,12 +485,12 @@ typedef int (*task_finished_fn)(int result,
>    * API reads that setting.
>    */
>   extern int run_processes_parallel_ungroup;
> -void run_processes_parallel(int n,
> +void run_processes_parallel(size_t n,
>   			    get_next_task_fn,
>   			    start_failure_fn,
>   			    task_finished_fn,
>   			    void *pp_cb);
> -void run_processes_parallel_tr2(int n, get_next_task_fn, start_failure_fn,
> +void run_processes_parallel_tr2(size_t n, get_next_task_fn, start_failure_fn,
>   				task_finished_fn, void *pp_cb,
>   				const char *tr2_category, const char *tr2_label);
>   
Previous: Ævar Arnfjörð BjarmasonNext: Ævar Arnfjörð Bjarmason
Message 61 of 79 in “run-command API: pass functions & opts via struct”
  1. 00/15 run-command API: pass functions & opts via structÆvar Arnfjörð Bjarmason, Sep 30, 2022
  2. 01/15 hook tests: fix redirection logic error in 96e7225b310Ævar Arnfjörð Bjarmason, Sep 30, 2022
  3. 02/15 submodule tests: reset "trace.out" between "grep" invocationsÆvar Arnfjörð Bjarmason, Sep 30, 2022
  4. 03/15 run-command tests: test stdout of run_command_parallel()Ævar Arnfjörð Bjarmason, Sep 30, 2022
  5. 06/15 run-command API: have "run_processes_parallel{,_tr2}()" return voidÆvar Arnfjörð Bjarmason, Sep 30, 2022
  6. Phillip WoodOct 7, 2022
  7. 05/15 run-command tests: use "return", not "exit"Ævar Arnfjörð Bjarmason, Sep 30, 2022
  8. Phillip WoodOct 7, 2022
  9. 04/15 run-command test helper: use "else if" patternÆvar Arnfjörð Bjarmason, Sep 30, 2022
  10. 09/15 run-command.c: add an initializer for "struct parallel_processes"Ævar Arnfjörð Bjarmason, Sep 30, 2022
  11. 07/15 run-command API: make "jobs" parameter an "unsigned int"Ævar Arnfjörð Bjarmason, Sep 30, 2022
  12. Calvin WanOct 4, 2022
  13. Phillip WoodOct 7, 2022
  14. 13/15 run-command API: move *_tr2() users to "run_processes_parallel()"Ævar Arnfjörð Bjarmason, Sep 30, 2022
  15. 10/15 run-command API: add nascent "struct run_process_parallel_opts"Ævar Arnfjörð Bjarmason, Sep 30, 2022
  16. Phillip WoodOct 7, 2022
  17. 08/15 run-command API: don't fall back on online_cpus()Ævar Arnfjörð Bjarmason, Sep 30, 2022
  18. Phillip WoodOct 7, 2022
  19. 11/15 run-command API: make run_process_parallel{,_tr2}() thin wrappersÆvar Arnfjörð Bjarmason, Sep 30, 2022
  20. 14/15 run-command.c: don't copy *_fn to "struct parallel_processes"Ævar Arnfjörð Bjarmason, Sep 30, 2022
  21. 12/15 run-command API: have run_process_parallel() take an "opts" structÆvar Arnfjörð Bjarmason, Sep 30, 2022
  22. 15/15 run-command.c: don't copy "ungroup" to "struct parallel_processes"Ævar Arnfjörð Bjarmason, Sep 30, 2022
  23. Calvin WanOct 4, 2022
  24. Phillip WoodOct 7, 2022
  25. Junio C HamanoOct 7, 2022
  26. 00/22 run-command API: pass functions & opts via structÆvar Arnfjörð Bjarmason, Oct 12, 2022
  27. 01/22 hook tests: fix redirection logic error in 96e7225b310Ævar Arnfjörð Bjarmason, Oct 12, 2022
  28. 02/22 submodule tests: reset "trace.out" between "grep" invocationsÆvar Arnfjörð Bjarmason, Oct 12, 2022
  29. 04/22 run-command test helper: use "else if" patternÆvar Arnfjörð Bjarmason, Oct 12, 2022
  30. 03/22 run-command tests: test stdout of run_command_parallel()Ævar Arnfjörð Bjarmason, Oct 12, 2022
  31. 05/22 run-command API: have "run_processes_parallel{,_tr2}()" return voidÆvar Arnfjörð Bjarmason, Oct 12, 2022
  32. 06/22 run-command tests: use "return", not "exit"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  33. 07/22 run-command.c: remove dead assignment in while-loopÆvar Arnfjörð Bjarmason, Oct 12, 2022
  34. 08/22 run-command.c: use C99 "for (TYPE VAR = ..." syntax where usefulÆvar Arnfjörð Bjarmason, Oct 12, 2022
  35. Phillip WoodOct 12, 2022
  36. Junio C HamanoOct 12, 2022
  37. 10/22 run-command API: don't fall back on online_cpus()Ævar Arnfjörð Bjarmason, Oct 12, 2022
  38. Phillip WoodOct 12, 2022
  39. 11/22 run-command.c: use designated init for pp_init(), add "const"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  40. 09/22 run-command API: make "n" parameter a "size_t"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  41. Phillip WoodOct 12, 2022
  42. 13/22 run-command API: make run_process_parallel{,_tr2}() thin wrappersÆvar Arnfjörð Bjarmason, Oct 12, 2022
  43. Phillip WoodOct 12, 2022
  44. 12/22 run-command API: add nascent "struct run_process_parallel_opts"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  45. 14/22 run-command API: have run_process_parallel() take an "opts" structÆvar Arnfjörð Bjarmason, Oct 12, 2022
  46. 15/22 run-command API: move *_tr2() users to "run_processes_parallel()"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  47. 16/22 run-command.c: make "struct parallel_processes" const if possibleÆvar Arnfjörð Bjarmason, Oct 12, 2022
  48. 17/22 run-command.c: don't copy *_fn to "struct parallel_processes"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  49. 18/22 run-command.c: don't copy "ungroup" to "struct parallel_processes"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  50. 19/22 run-command.c: don't copy "data" to "struct parallel_processes"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  51. 21/22 run-command.c: pass "opts" further down, and use "opts->processes"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  52. 20/22 run-command.c: use "opts->processes", not "pp->max_processes"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  53. 22/22 run-command.c: remove "pp->max_processes", add "const" to signal() handlerÆvar Arnfjörð Bjarmason, Oct 12, 2022
  54. Ævar Arnfjörð BjarmasonOct 12, 2022
  55. Phillip WoodOct 12, 2022
  56. 00/15 run-command API: pass functions & opts via structÆvar Arnfjörð Bjarmason, Oct 12, 2022
  57. 01/15 run-command test helper: use "else if" patternÆvar Arnfjörð Bjarmason, Oct 12, 2022
  58. 02/15 run-command API: have "run_processes_parallel{,_tr2}()" return voidÆvar Arnfjörð Bjarmason, Oct 12, 2022
  59. 03/15 run-command tests: use "return", not "exit"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  60. 04/15 run-command API: make "n" parameter a "size_t"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  61. Phillip WoodOct 14, 2022
  62. 05/15 run-command API: don't fall back on online_cpus()Ævar Arnfjörð Bjarmason, Oct 12, 2022
  63. 06/15 run-command.c: use designated init for pp_init(), add "const"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  64. 08/15 run-command API: move *_tr2() users to "run_processes_parallel()"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  65. 07/15 run-command API: have run_process_parallel() take an "opts" structÆvar Arnfjörð Bjarmason, Oct 12, 2022
  66. Phillip WoodOct 14, 2022
  67. 09/15 run-command.c: make "struct parallel_processes" const if possibleÆvar Arnfjörð Bjarmason, Oct 12, 2022
  68. 13/15 run-command.c: use "opts->processes", not "pp->max_processes"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  69. 11/15 run-command.c: don't copy "ungroup" to "struct parallel_processes"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  70. 10/15 run-command.c: don't copy *_fn to "struct parallel_processes"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  71. 14/15 run-command.c: pass "opts" further down, and use "opts->processes"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  72. 15/15 run-command.c: remove "max_processes", add "const" to signal() handlerÆvar Arnfjörð Bjarmason, Oct 12, 2022
  73. Glen ChooOct 13, 2022
  74. 12/15 run-command.c: don't copy "data" to "struct parallel_processes"Ævar Arnfjörð Bjarmason, Oct 12, 2022
  75. Calvin WanOct 13, 2022
  76. Junio C HamanoOct 13, 2022
  77. Phillip WoodOct 14, 2022
  78. Ævar Arnfjörð BjarmasonOct 14, 2022
  79. Junio C HamanoOct 14, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.