Changes since v2 - more cleanups in grep.c, read-cache.c and index-pack.c - the send-pack.c changes are back, but this time I just add async_with_fork() to move NO_PTHREADS back in run-command.c For grep.c and read-cache.c, changes are split in two patches. The first one is a dumb, mechanical conversion from #ifdef to if and is straightforward. The second one makes "no thread" use "one thread" code path and needs more careful review. Diff against nd/pthreads diff --git a/builtin/grep.c b/builtin/grep.c index 6dd15dbaa2..de3f568cee 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -69,13 +69,11 @@ static pthread_mutex_t grep_mutex; static inline void grep_lock(void) { - assert(num_threads); pthread_mutex_lock(&grep_mutex); } static inline void grep_unlock(void) { - assert(num_threads); pthread_mutex_unlock(&grep_mutex); } @@ -234,7 +232,7 @@ static int wait_all(void) int i; if (!HAVE_THREADS) - return 0; + BUG("Never call this function unless you have started threads"); grep_lock(); all_work_added = 1; @@ -279,14 +277,14 @@ static int grep_cmd_config(const char *var, const char *value, void *cb) if (num_threads < 0) die(_("invalid number of threads specified (%d) for %s"), num_threads, var); - else if (!HAVE_THREADS && num_threads && num_threads != 1) { + else if (!HAVE_THREADS && num_threads > 1) { /* * TRANSLATORS: %s is the configuration * variable for tweaking threads, currently * grep.threads */ warning(_("no threads support, ignoring %s"), var); - num_threads = 0; + num_threads = 1; } } @@ -323,7 +321,7 @@ static int grep_oid(struct grep_opt *opt, const struct object_id *oid, grep_source_init(&gs, GREP_SOURCE_OID, pathbuf.buf, path, oid); strbuf_release(&pathbuf); - if (HAVE_THREADS && num_threads) { + if (num_threads > 1) { /* * add_work() copies gs and thus assumes ownership of * its fields, so do not call grep_source_clear() @@ -353,7 +351,7 @@ static int grep_file(struct grep_opt *opt, const char *filename) grep_source_init(&gs, GREP_SOURCE_FILE, buf.buf, filename, filename); strbuf_release(&buf); - if (HAVE_THREADS && num_threads) { + if (num_threads > 1) { /* * add_work() copies gs and thus assumes ownership of * its fields, so do not call grep_source_clear() @@ -1025,36 +1023,34 @@ int cmd_grep(int argc, const char **argv, const char *prefix) pathspec.recursive = 1; pathspec.recurse_submodules = !!recurse_submodules; - if (HAVE_THREADS) { - if (list.nr || cached || show_in_pager) - num_threads = 0; - else if (num_threads == 0) - num_threads = GREP_NUM_THREADS_DEFAULT; - else if (num_threads < 0) - die(_("invalid number of threads specified (%d)"), num_threads); - if (num_threads == 1) - num_threads = 0; + if (list.nr || cached || show_in_pager) { + if (num_threads > 1) + warning(_("invalid option combination, ignoring --threads")); + num_threads = 1; + } else if (!HAVE_THREADS && num_threads > 1) { + warning(_("no threads support, ignoring --threads")); + num_threads = 1; + } else if (num_threads < 0) + die(_("invalid number of threads specified (%d)"), num_threads); + else if (num_threads == 0) + num_threads = HAVE_THREADS ? GREP_NUM_THREADS_DEFAULT : 1; + + if (num_threads > 1) { + if (!HAVE_THREADS) + BUG("Somebody got num_threads calculation wrong!"); + if (!(opt.name_only || opt.unmatch_name_only || opt.count) + && (opt.pre_context || opt.post_context || + opt.file_break || opt.funcbody)) + skip_first_line = 1; + start_threads(&opt); } else { - if (num_threads) - warning(_("no threads support, ignoring --threads")); - num_threads = 0; - } - - if (!num_threads) /* * The compiled patterns on the main path are only * used when not using threading. Otherwise - * start_threads() below calls compile_grep_patterns() + * start_threads() above calls compile_grep_patterns() * for each thread. */ compile_grep_patterns(&opt); - - if (HAVE_THREADS && num_threads) { - if (!(opt.name_only || opt.unmatch_name_only || opt.count) - && (opt.pre_context || opt.post_context || - opt.file_break || opt.funcbody)) - skip_first_line = 1; - start_threads(&opt); } if (show_in_pager && (cached || list.nr)) @@ -1106,7 +1102,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) hit = grep_objects(&opt, &pathspec, &list); } - if (num_threads) + if (num_threads > 1) hit |= wait_all(); if (hit && show_in_pager) run_pager(&opt, prefix); diff --git a/builtin/index-pack.c b/builtin/index-pack.c index bbd66ca025..682042579b 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1501,9 +1501,8 @@ static int git_index_pack_config(const char *k, const char *v, void *cb) if (nr_threads < 0) die(_("invalid number of threads specified (%d)"), nr_threads); - if (!HAVE_THREADS) { - if (nr_threads != 1) - warning(_("no threads support, ignoring %s"), k); + if (!HAVE_THREADS && nr_threads != 1) { + warning(_("no threads support, ignoring %s"), k); nr_threads = 1; } return 0; @@ -1693,10 +1692,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix) nr_threads = strtoul(arg+10, &end, 0); if (!arg[10] || *end || nr_threads < 0) usage(index_pack_usage); - if (!HAVE_THREADS) { - if (nr_threads != 1) - warning(_("no threads support, " - "ignoring %s"), arg); + if (!HAVE_THREADS && nr_threads != 1) { + warning(_("no threads support, ignoring %s"), arg); nr_threads = 1; } } else if (starts_with(arg, "--pack_header=")) { diff --git a/read-cache.c b/read-cache.c index 4307b9a7bf..c510f598b1 100644 --- a/read-cache.c +++ b/read-cache.c @@ -2170,20 +2170,19 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist) src_offset = sizeof(*hdr); - if (HAVE_THREADS) { - nr_threads = git_config_get_index_threads(); + nr_threads = git_config_get_index_threads(); - /* TODO: does creating more threads than cores help? */ - if (!nr_threads) { - nr_threads = istate->cache_nr / THREAD_COST; - cpus = online_cpus(); - if (nr_threads > cpus) - nr_threads = cpus; - } - } else { - nr_threads = 1; + /* TODO: does creating more threads than cores help? */ + if (!nr_threads) { + nr_threads = istate->cache_nr / THREAD_COST; + cpus = online_cpus(); + if (nr_threads > cpus) + nr_threads = cpus; } + if (!HAVE_THREADS) + nr_threads = 1; + if (nr_threads > 1) { extension_offset = read_eoie_extension(mmap, mmap_size); if (extension_offset) { @@ -2216,12 +2215,11 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist) istate->timestamp.nsec = ST_MTIME_NSEC(st); /* if we created a thread, join it otherwise load the extensions on the primary thread */ - if (HAVE_THREADS && extension_offset) { + if (extension_offset) { int ret = pthread_join(p.pthread, NULL); if (ret) die(_("unable to join load_index_extensions thread: %s"), strerror(ret)); - } - if (!extension_offset) { + } else { p.src_offset = src_offset; load_index_extensions(&p); } @@ -2860,7 +2858,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile, * strip_extensions parameter as we need it when loading the shared * index. */ - if (HAVE_THREADS && ieot) { + if (ieot) { struct strbuf sb = STRBUF_INIT; write_ieot_extension(&sb, ieot); diff --git a/run-command.c b/run-command.c index 26154ba257..decf3239bd 100644 --- a/run-command.c +++ b/run-command.c @@ -1246,6 +1246,15 @@ int finish_async(struct async *async) #endif } +int async_with_fork(void) +{ +#ifdef NO_PTHREADS + return 1; +#else + return 0; +#endif +} + const char *find_hook(const char *name) { static struct strbuf path = STRBUF_INIT; diff --git a/run-command.h b/run-command.h index 3932420ec8..68f5369fc2 100644 --- a/run-command.h +++ b/run-command.h @@ -1,9 +1,7 @@ #ifndef RUN_COMMAND_H #define RUN_COMMAND_H -#ifndef NO_PTHREADS -#include <pthread.h> -#endif +#include "thread-utils.h" #include "argv-array.h" @@ -143,6 +141,7 @@ struct async { int start_async(struct async *async); int finish_async(struct async *async); int in_async(void); +int async_with_fork(void); void check_pipe(int err); /** diff --git a/send-pack.c b/send-pack.c index e920ca57df..f692686770 100644 --- a/send-pack.c +++ b/send-pack.c @@ -203,9 +203,8 @@ static int receive_status(int in, struct ref *refs) static int sideband_demux(int in, int out, void *data) { int *fd = data, ret; -#ifdef NO_PTHREADS - close(fd[1]); -#endif + if (async_with_fork()) + close(fd[1]); ret = recv_sideband("send-pack", fd[0], out); close(out); return ret; Nguyễn Thái Ngọc Duy (14): thread-utils: macros to unconditionally compile pthreads API run-command.h: include thread-utils.h instead of pthread.h send-pack.c: move async's #ifdef NO_PTHREADS back to run-command.c index-pack: remove #ifdef NO_PTHREADS name-hash.c: remove #ifdef NO_PTHREADS attr.c: remove #ifdef NO_PTHREADS grep: remove #ifdef NO_PTHREADS grep: clean up num_threads handling preload-index.c: remove #ifdef NO_PTHREADS pack-objects: remove #ifdef NO_PTHREADS read-cache.c: remove #ifdef NO_PTHREADS read-cache.c: reduce branching based on HAVE_THREADS read-cache.c: initialize copy_len to shut up gcc 8 Clean up pthread_create() error handling Makefile | 2 +- attr.c | 14 -------- builtin/grep.c | 79 ++++++++++++++++-------------------------- builtin/index-pack.c | 63 ++++++++------------------------- builtin/pack-objects.c | 26 ++------------ grep.c | 6 ---- grep.h | 6 ---- name-hash.c | 38 ++++++++------------ pack-objects.h | 6 ---- preload-index.c | 23 +++++------- read-cache.c | 37 ++++++-------------- run-command.c | 11 +++++- run-command.h | 5 ++- send-pack.c | 5 ++- thread-utils.c | 48 +++++++++++++++++++++++++ thread-utils.h | 48 +++++++++++++++++++++++-- 16 files changed, 186 insertions(+), 231 deletions(-) -- 2.19.1.1005.gac84295441