grep: clean up num_threads handling

When NO_PTHREADS is still used in this file, we have two separate code paths for thread and no thread support. The latter will always have num_threads remain zero while the former uses num_threads zero as "default number of threads". With recent changes blur the line between thread and no-thread support, this num_threads handling becomes a bit strange so let's redefine it like this: - num_threads == 0 means default number of threads and should become positive after all configuration and option parsing is done if multithread is supported. - num_threads <= 1 runs no threads. It does not matter if the platform supports threading or not. - num_threads > 1 will run multiple threads and is invalid if HAVE_THREADS is false. pthread API is only used in this case. PS. a new warning is also added when num_threads is forced back to one because a thread-incompatible option is specified. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Nov 3, 2018 at 09:48 UTC fd6263fb733e50cfbcf857136388bf47d9c5151f
1 file changed +27 -31
builtin/grep.c
+27 -31
@@ -69,13 +69,11 @@ static pthread_mutex_t grep_mutex;
69
70 static inline void grep_lock(void)
71 {
72 - assert(num_threads);
72 pthread_mutex_lock(&grep_mutex);
73 }
74
75 static inline void grep_unlock(void)
76 {
78 - assert(num_threads);
77 pthread_mutex_unlock(&grep_mutex);
78 }
79
@@ -234,7 +232,7 @@ static int wait_all(void)
232 int i;
233
234 if (!HAVE_THREADS)
237 - return 0;
235 + BUG("Never call this function unless you have started threads");
236
237 grep_lock();
238 all_work_added = 1;
@@ -279,14 +277,14 @@ static int grep_cmd_config(const char *var, const char *value, void *cb)
277 if (num_threads < 0)
278 die(_("invalid number of threads specified (%d) for %s"),
279 num_threads, var);
282 - else if (!HAVE_THREADS && num_threads && num_threads != 1) {
280 + else if (!HAVE_THREADS && num_threads > 1) {
281 /*
282 * TRANSLATORS: %s is the configuration
283 * variable for tweaking threads, currently
284 * grep.threads
285 */
286 warning(_("no threads support, ignoring %s"), var);
289 - num_threads = 0;
287 + num_threads = 1;
288 }
289 }
290
@@ -323,7 +321,7 @@ static int grep_oid(struct grep_opt *opt, const struct object_id *oid,
321 grep_source_init(&gs, GREP_SOURCE_OID, pathbuf.buf, path, oid);
322 strbuf_release(&pathbuf);
323
326 - if (HAVE_THREADS && num_threads) {
324 + if (num_threads > 1) {
325 /*
326 * add_work() copies gs and thus assumes ownership of
327 * its fields, so do not call grep_source_clear()
@@ -353,7 +351,7 @@ static int grep_file(struct grep_opt *opt, const char *filename)
351 grep_source_init(&gs, GREP_SOURCE_FILE, buf.buf, filename, filename);
352 strbuf_release(&buf);
353
356 - if (HAVE_THREADS && num_threads) {
354 + if (num_threads > 1) {
355 /*
356 * add_work() copies gs and thus assumes ownership of
357 * its fields, so do not call grep_source_clear()
@@ -1025,36 +1023,34 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
1023 pathspec.recursive = 1;
1024 pathspec.recurse_submodules = !!recurse_submodules;
1025
1028 - if (HAVE_THREADS) {
1029 - if (list.nr || cached || show_in_pager)
1030 - num_threads = 0;
1031 - else if (num_threads == 0)
1032 - num_threads = GREP_NUM_THREADS_DEFAULT;
1033 - else if (num_threads < 0)
1034 - die(_("invalid number of threads specified (%d)"), num_threads);
1035 - if (num_threads == 1)
1036 - num_threads = 0;
1026 + if (list.nr || cached || show_in_pager) {
1027 + if (num_threads > 1)
1028 + warning(_("invalid option combination, ignoring --threads"));
1029 + num_threads = 1;
1030 + } else if (!HAVE_THREADS && num_threads > 1) {
1031 + warning(_("no threads support, ignoring --threads"));
1032 + num_threads = 1;
1033 + } else if (num_threads < 0)
1034 + die(_("invalid number of threads specified (%d)"), num_threads);
1035 + else if (num_threads == 0)
1036 + num_threads = HAVE_THREADS ? GREP_NUM_THREADS_DEFAULT : 1;
1037 +
1038 + if (num_threads > 1) {
1039 + if (!HAVE_THREADS)
1040 + BUG("Somebody got num_threads calculation wrong!");
1041 + if (!(opt.name_only || opt.unmatch_name_only || opt.count)
1042 + && (opt.pre_context || opt.post_context ||
1043 + opt.file_break || opt.funcbody))
1044 + skip_first_line = 1;
1045 + start_threads(&opt);
1046 } else {
1038 - if (num_threads)
1039 - warning(_("no threads support, ignoring --threads"));
1040 - num_threads = 0;
1041 - }
1042 -
1043 - if (!num_threads)
1047 /*
1048 * The compiled patterns on the main path are only
1049 * used when not using threading. Otherwise
1047 - * start_threads() below calls compile_grep_patterns()
1050 + * start_threads() above calls compile_grep_patterns()
1051 * for each thread.
1052 */
1053 compile_grep_patterns(&opt);
1051 -
1052 - if (HAVE_THREADS && num_threads) {
1053 - if (!(opt.name_only || opt.unmatch_name_only || opt.count)
1054 - && (opt.pre_context || opt.post_context ||
1055 - opt.file_break || opt.funcbody))
1056 - skip_first_line = 1;
1057 - start_threads(&opt);
1054 }
1055
1056 if (show_in_pager && (cached || list.nr))
@@ -1106,7 +1102,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
1102 hit = grep_objects(&opt, &pathspec, &list);
1103 }
1104
1109 - if (num_threads)
1105 + if (num_threads > 1)
1106 hit |= wait_all();
1107 if (hit && show_in_pager)
1108 run_pager(&opt, prefix);