Merge branch 'nd/pthreads'
authorJunio C Hamano <gitster@pobox.com>
Sun, 18 Nov 2018 09:23:52 +0000 (18:23 +0900)
committerJunio C Hamano <gitster@pobox.com>
Sun, 18 Nov 2018 09:23:52 +0000 (18:23 +0900)
The codebase has been cleaned up to reduce "#ifndef NO_PTHREADS".

* nd/pthreads:
  Clean up pthread_create() error handling
  read-cache.c: initialize copy_len to shut up gcc 8
  read-cache.c: reduce branching based on HAVE_THREADS
  read-cache.c: remove #ifdef NO_PTHREADS
  pack-objects: remove #ifdef NO_PTHREADS
  preload-index.c: remove #ifdef NO_PTHREADS
  grep: clean up num_threads handling
  grep: remove #ifdef NO_PTHREADS
  attr.c: remove #ifdef NO_PTHREADS
  name-hash.c: remove #ifdef NO_PTHREADS
  index-pack: remove #ifdef NO_PTHREADS
  send-pack.c: move async's #ifdef NO_PTHREADS back to run-command.c
  run-command.h: include thread-utils.h instead of pthread.h
  thread-utils: macros to unconditionally compile pthreads API

16 files changed:
Makefile
attr.c
builtin/grep.c
builtin/index-pack.c
builtin/pack-objects.c
grep.c
grep.h
name-hash.c
pack-objects.h
preload-index.c
read-cache.c
run-command.c
run-command.h
send-pack.c
thread-utils.c
thread-utils.h

index 016fdcd..3b48e86 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -993,6 +993,7 @@ LIB_OBJS += sub-process.o
 LIB_OBJS += symlinks.o
 LIB_OBJS += tag.o
 LIB_OBJS += tempfile.o
+LIB_OBJS += thread-utils.o
 LIB_OBJS += tmp-objdir.o
 LIB_OBJS += trace.o
 LIB_OBJS += trailer.o
@@ -1677,7 +1678,6 @@ ifdef NO_PTHREADS
 else
        BASIC_CFLAGS += $(PTHREAD_CFLAGS)
        EXTLIBS += $(PTHREAD_LIBS)
-       LIB_OBJS += thread-utils.o
 endif
 
 ifdef HAVE_PATHS_H
diff --git a/attr.c b/attr.c
index 60d2847..eaece66 100644 (file)
--- a/attr.c
+++ b/attr.c
@@ -41,23 +41,17 @@ const char *git_attr_name(const struct git_attr *attr)
 
 struct attr_hashmap {
        struct hashmap map;
-#ifndef NO_PTHREADS
        pthread_mutex_t mutex;
-#endif
 };
 
 static inline void hashmap_lock(struct attr_hashmap *map)
 {
-#ifndef NO_PTHREADS
        pthread_mutex_lock(&map->mutex);
-#endif
 }
 
 static inline void hashmap_unlock(struct attr_hashmap *map)
 {
-#ifndef NO_PTHREADS
        pthread_mutex_unlock(&map->mutex);
-#endif
 }
 
 /*
@@ -498,23 +492,17 @@ static struct check_vector {
        size_t nr;
        size_t alloc;
        struct attr_check **checks;
-#ifndef NO_PTHREADS
        pthread_mutex_t mutex;
-#endif
 } check_vector;
 
 static inline void vector_lock(void)
 {
-#ifndef NO_PTHREADS
        pthread_mutex_lock(&check_vector.mutex);
-#endif
 }
 
 static inline void vector_unlock(void)
 {
-#ifndef NO_PTHREADS
        pthread_mutex_unlock(&check_vector.mutex);
-#endif
 }
 
 static void check_vector_add(struct attr_check *c)
@@ -1181,8 +1169,6 @@ void git_all_attrs(const struct index_state *istate,
 
 void attr_start(void)
 {
-#ifndef NO_PTHREADS
        pthread_mutex_init(&g_attr_hashmap.mutex, NULL);
        pthread_mutex_init(&check_vector.mutex, NULL);
-#endif
 }
index 56e4a11..cca87cf 100644 (file)
@@ -34,7 +34,6 @@ static int recurse_submodules;
 #define GREP_NUM_THREADS_DEFAULT 8
 static int num_threads;
 
-#ifndef NO_PTHREADS
 static pthread_t *threads;
 
 /* We use one producer thread and THREADS consumer
@@ -70,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,6 +231,9 @@ static int wait_all(void)
        int hit = 0;
        int i;
 
+       if (!HAVE_THREADS)
+               BUG("Never call this function unless you have started threads");
+
        grep_lock();
        all_work_added = 1;
 
@@ -265,13 +265,6 @@ static int wait_all(void)
 
        return hit;
 }
-#else /* !NO_PTHREADS */
-
-static int wait_all(void)
-{
-       return 0;
-}
-#endif
 
 static int grep_cmd_config(const char *var, const char *value, void *cb)
 {
@@ -284,17 +277,15 @@ 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);
-#ifdef NO_PTHREADS
-               else if (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;
                }
-#endif
        }
 
        if (!strcmp(var, "submodule.recurse"))
@@ -330,17 +321,14 @@ 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);
 
-#ifndef NO_PTHREADS
-       if (num_threads) {
+       if (num_threads > 1) {
                /*
                 * add_work() copies gs and thus assumes ownership of
                 * its fields, so do not call grep_source_clear()
                 */
                add_work(opt, &gs);
                return 0;
-       } else
-#endif
-       {
+       } else {
                int hit;
 
                hit = grep_source(opt, &gs);
@@ -363,17 +351,14 @@ 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);
 
-#ifndef NO_PTHREADS
-       if (num_threads) {
+       if (num_threads > 1) {
                /*
                 * add_work() copies gs and thus assumes ownership of
                 * its fields, so do not call grep_source_clear()
                 */
                add_work(opt, &gs);
                return 0;
-       } else
-#endif
-       {
+       } else {
                int hit;
 
                hit = grep_source(opt, &gs);
@@ -1049,39 +1034,35 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
        pathspec.recursive = 1;
        pathspec.recurse_submodules = !!recurse_submodules;
 
-#ifndef NO_PTHREADS
-       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;
-#else
-       if (num_threads)
+       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 = 0;
-#endif
+               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)
+       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 {
                /*
                 * 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);
-
-#ifndef NO_PTHREADS
-       if (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);
        }
-#endif
 
        if (show_in_pager && (cached || list.nr))
                die(_("--open-files-in-pager only works on the worktree"));
@@ -1132,7 +1113,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);
index 2004e25..6820425 100644 (file)
@@ -42,9 +42,7 @@ struct base_data {
 };
 
 struct thread_local {
-#ifndef NO_PTHREADS
        pthread_t thread;
-#endif
        struct base_data *base_cache;
        size_t base_cache_used;
        int pack_fd;
@@ -98,8 +96,6 @@ static uint32_t input_crc32;
 static int input_fd, output_fd;
 static const char *curr_pack;
 
-#ifndef NO_PTHREADS
-
 static struct thread_local *thread_data;
 static int nr_dispatched;
 static int threads_active;
@@ -179,26 +175,6 @@ static void cleanup_thread(void)
        free(thread_data);
 }
 
-#else
-
-#define read_lock()
-#define read_unlock()
-
-#define counter_lock()
-#define counter_unlock()
-
-#define work_lock()
-#define work_unlock()
-
-#define deepest_delta_lock()
-#define deepest_delta_unlock()
-
-#define type_cas_lock()
-#define type_cas_unlock()
-
-#endif
-
-
 static int mark_link(struct object *obj, int type, void *data, struct fsck_options *options)
 {
        if (!obj)
@@ -364,22 +340,20 @@ static NORETURN void bad_object(off_t offset, const char *format, ...)
 
 static inline struct thread_local *get_thread_data(void)
 {
-#ifndef NO_PTHREADS
-       if (threads_active)
-               return pthread_getspecific(key);
-       assert(!threads_active &&
-              "This should only be reached when all threads are gone");
-#endif
+       if (HAVE_THREADS) {
+               if (threads_active)
+                       return pthread_getspecific(key);
+               assert(!threads_active &&
+                      "This should only be reached when all threads are gone");
+       }
        return &nothread_data;
 }
 
-#ifndef NO_PTHREADS
 static void set_thread_data(struct thread_local *data)
 {
        if (threads_active)
                pthread_setspecific(key, data);
 }
-#endif
 
 static struct base_data *alloc_base_data(void)
 {
@@ -1092,7 +1066,6 @@ static void resolve_base(struct object_entry *obj)
        find_unresolved_deltas(base_obj);
 }
 
-#ifndef NO_PTHREADS
 static void *threaded_second_pass(void *data)
 {
        set_thread_data(data);
@@ -1116,7 +1089,6 @@ static void *threaded_second_pass(void *data)
        }
        return NULL;
 }
-#endif
 
 /*
  * First pass:
@@ -1213,7 +1185,6 @@ static void resolve_deltas(void)
                progress = start_progress(_("Resolving deltas"),
                                          nr_ref_deltas + nr_ofs_deltas);
 
-#ifndef NO_PTHREADS
        nr_dispatched = 0;
        if (nr_threads > 1 || getenv("GIT_FORCE_THREADS")) {
                init_thread();
@@ -1229,7 +1200,6 @@ static void resolve_deltas(void)
                cleanup_thread();
                return;
        }
-#endif
 
        for (i = 0; i < nr_objects; i++) {
                struct object_entry *obj = &objects[i];
@@ -1531,11 +1501,10 @@ 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);
-#ifdef NO_PTHREADS
-               if (nr_threads != 1)
+               if (!HAVE_THREADS && nr_threads != 1) {
                        warning(_("no threads support, ignoring %s"), k);
-               nr_threads = 1;
-#endif
+                       nr_threads = 1;
+               }
                return 0;
        }
        return git_default_config(k, v, cb);
@@ -1723,12 +1692,10 @@ 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);
-#ifdef NO_PTHREADS
-                               if (nr_threads != 1)
-                                       warning(_("no threads support, "
-                                                 "ignoring %s"), arg);
-                               nr_threads = 1;
-#endif
+                               if (!HAVE_THREADS && nr_threads != 1) {
+                                       warning(_("no threads support, ignoring %s"), arg);
+                                       nr_threads = 1;
+                               }
                        } else if (starts_with(arg, "--pack_header=")) {
                                struct pack_header *hdr;
                                char *c;
@@ -1791,14 +1758,12 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
        if (strict)
                opts.flags |= WRITE_IDX_STRICT;
 
-#ifndef NO_PTHREADS
-       if (!nr_threads) {
+       if (HAVE_THREADS && !nr_threads) {
                nr_threads = online_cpus();
                /* An experiment showed that more threads does not mean faster */
                if (nr_threads > 3)
                        nr_threads = 3;
        }
-#endif
 
        curr_pack = open_pack_file(pack_name);
        parse_pack_header();
index c99ee79..2193054 100644 (file)
@@ -1953,8 +1953,6 @@ static int delta_cacheable(unsigned long src_size, unsigned long trg_size,
        return 0;
 }
 
-#ifndef NO_PTHREADS
-
 /* Protect access to object database */
 static pthread_mutex_t read_mutex;
 #define read_lock()            pthread_mutex_lock(&read_mutex)
@@ -1979,16 +1977,6 @@ static pthread_mutex_t progress_mutex;
  * ahead in the list because they can be stolen and would need
  * progress_mutex for protection.
  */
-#else
-
-#define read_lock()            (void)0
-#define read_unlock()          (void)0
-#define cache_lock()           (void)0
-#define cache_unlock()         (void)0
-#define progress_lock()                (void)0
-#define progress_unlock()      (void)0
-
-#endif
 
 /*
  * Return the size of the object without doing any delta
@@ -2347,8 +2335,6 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
        free(array);
 }
 
-#ifndef NO_PTHREADS
-
 static void try_to_free_from_threads(size_t size)
 {
        read_lock();
@@ -2577,10 +2563,6 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,
        free(p);
 }
 
-#else
-#define ll_find_deltas(l, s, w, d, p)  find_deltas(l, &s, w, d, p)
-#endif
-
 static void add_tag_chain(const struct object_id *oid)
 {
        struct tag *tag;
@@ -2733,12 +2715,10 @@ static int git_pack_config(const char *k, const char *v, void *cb)
                if (delta_search_threads < 0)
                        die(_("invalid number of threads specified (%d)"),
                            delta_search_threads);
-#ifdef NO_PTHREADS
-               if (delta_search_threads != 1) {
+               if (!HAVE_THREADS && delta_search_threads != 1) {
                        warning(_("no threads support, ignoring %s"), k);
                        delta_search_threads = 0;
                }
-#endif
                return 0;
        }
        if (!strcmp(k, "pack.indexversion")) {
@@ -3402,10 +3382,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
        if (!delta_search_threads)      /* --threads=0 means autodetect */
                delta_search_threads = online_cpus();
 
-#ifdef NO_PTHREADS
-       if (delta_search_threads != 1)
+       if (!HAVE_THREADS && delta_search_threads != 1)
                warning(_("no threads support, ignoring --threads"));
-#endif
        if (!pack_to_stdout && !pack_size_limit)
                pack_size_limit = pack_size_limit_cfg;
        if (pack_to_stdout && pack_size_limit)
diff --git a/grep.c b/grep.c
index f6bd89e..4db1510 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -1513,7 +1513,6 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
        }
 }
 
-#ifndef NO_PTHREADS
 int grep_use_locks;
 
 /*
@@ -1539,11 +1538,6 @@ static inline void grep_attr_unlock(void)
  */
 pthread_mutex_t grep_read_mutex;
 
-#else
-#define grep_attr_lock()
-#define grep_attr_unlock()
-#endif
-
 static int match_funcname(struct grep_opt *opt, struct grep_source *gs, char *bol, char *eol)
 {
        xdemitconf_t *xecfg = opt->priv;
diff --git a/grep.h b/grep.h
index 1a57d12..fb04893 100644 (file)
--- a/grep.h
+++ b/grep.h
@@ -229,7 +229,6 @@ int grep_source(struct grep_opt *opt, struct grep_source *gs);
 extern struct grep_opt *grep_opt_dup(const struct grep_opt *opt);
 extern int grep_threads_ok(const struct grep_opt *opt);
 
-#ifndef NO_PTHREADS
 /*
  * Mutex used around access to the attributes machinery if
  * opt->use_threads.  Must be initialized/destroyed by callers!
@@ -250,9 +249,4 @@ static inline void grep_read_unlock(void)
                pthread_mutex_unlock(&grep_read_mutex);
 }
 
-#else
-#define grep_read_lock()
-#define grep_read_unlock()
-#endif
-
 #endif
index 1fcda73..623ca69 100644 (file)
@@ -7,6 +7,7 @@
  */
 #define NO_THE_INDEX_COMPATIBILITY_MACROS
 #include "cache.h"
+#include "thread-utils.h"
 
 struct dir_entry {
        struct hashmap_entry ent;
@@ -131,22 +132,6 @@ static int cache_entry_cmp(const void *unused_cmp_data,
 static int lazy_try_threaded = 1;
 static int lazy_nr_dir_threads;
 
-#ifdef NO_PTHREADS
-
-static inline int lookup_lazy_params(struct index_state *istate)
-{
-       return 0;
-}
-
-static inline void threaded_lazy_init_name_hash(
-       struct index_state *istate)
-{
-}
-
-#else
-
-#include "thread-utils.h"
-
 /*
  * Set a minimum number of cache_entries that we will handle per
  * thread and use that to decide how many threads to run (upto
@@ -509,6 +494,7 @@ static inline void lazy_update_dir_ref_counts(
 static void threaded_lazy_init_name_hash(
        struct index_state *istate)
 {
+       int err;
        int nr_each;
        int k_start;
        int t;
@@ -516,6 +502,9 @@ static void threaded_lazy_init_name_hash(
        struct lazy_dir_thread_data *td_dir;
        struct lazy_name_thread_data *td_name;
 
+       if (!HAVE_THREADS)
+               return;
+
        k_start = 0;
        nr_each = DIV_ROUND_UP(istate->cache_nr, lazy_nr_dir_threads);
 
@@ -538,8 +527,9 @@ static void threaded_lazy_init_name_hash(
                if (k_start > istate->cache_nr)
                        k_start = istate->cache_nr;
                td_dir_t->k_end = k_start;
-               if (pthread_create(&td_dir_t->pthread, NULL, lazy_dir_thread_proc, td_dir_t))
-                       die("unable to create lazy_dir_thread");
+               err = pthread_create(&td_dir_t->pthread, NULL, lazy_dir_thread_proc, td_dir_t);
+               if (err)
+                       die(_("unable to create lazy_dir thread: %s"), strerror(err));
        }
        for (t = 0; t < lazy_nr_dir_threads; t++) {
                struct lazy_dir_thread_data *td_dir_t = td_dir + t;
@@ -559,13 +549,15 @@ static void threaded_lazy_init_name_hash(
         */
        td_name->istate = istate;
        td_name->lazy_entries = lazy_entries;
-       if (pthread_create(&td_name->pthread, NULL, lazy_name_thread_proc, td_name))
-               die("unable to create lazy_name_thread");
+       err = pthread_create(&td_name->pthread, NULL, lazy_name_thread_proc, td_name);
+       if (err)
+               die(_("unable to create lazy_name thread: %s"), strerror(err));
 
        lazy_update_dir_ref_counts(istate, lazy_entries);
 
-       if (pthread_join(td_name->pthread, NULL))
-               die("unable to join lazy_name_thread");
+       err = pthread_join(td_name->pthread, NULL);
+       if (err)
+               die(_("unable to join lazy_name thread: %s"), strerror(err));
 
        cleanup_dir_mutex();
 
@@ -574,8 +566,6 @@ static void threaded_lazy_init_name_hash(
        free(lazy_entries);
 }
 
-#endif
-
 static void lazy_init_name_hash(struct index_state *istate)
 {
 
index 86ee93f..feb6a6a 100644 (file)
@@ -145,9 +145,7 @@ struct packing_data {
        struct packed_git **in_pack_by_idx;
        struct packed_git **in_pack;
 
-#ifndef NO_PTHREADS
        pthread_mutex_t lock;
-#endif
 
        /*
         * This list contains entries for bases which we know the other side
@@ -169,15 +167,11 @@ void prepare_packing_data(struct packing_data *pdata);
 
 static inline void packing_data_lock(struct packing_data *pdata)
 {
-#ifndef NO_PTHREADS
        pthread_mutex_lock(&pdata->lock);
-#endif
 }
 static inline void packing_data_unlock(struct packing_data *pdata)
 {
-#ifndef NO_PTHREADS
        pthread_mutex_unlock(&pdata->lock);
-#endif
 }
 
 struct object_entry *packlist_alloc(struct packing_data *pdata,
index 222792c..c7dc3f2 100644 (file)
@@ -7,17 +7,7 @@
 #include "fsmonitor.h"
 #include "config.h"
 #include "progress.h"
-
-#ifdef NO_PTHREADS
-void preload_index(struct index_state *index,
-                         const struct pathspec *pathspec,
-                         unsigned int refresh_flags)
-{
-       ; /* nothing */
-}
-#else
-
-#include <pthread.h>
+#include "thread-utils.h"
 
 /*
  * Mostly randomly chosen maximum thread counts: we
@@ -108,7 +98,7 @@ void preload_index(struct index_state *index,
        struct thread_data data[MAX_PARALLEL];
        struct progress_data pd;
 
-       if (!core_preload_index)
+       if (!HAVE_THREADS || !core_preload_index)
                return;
 
        threads = index->cache_nr / THREAD_COST;
@@ -131,6 +121,8 @@ void preload_index(struct index_state *index,
 
        for (i = 0; i < threads; i++) {
                struct thread_data *p = data+i;
+               int err;
+
                p->index = index;
                if (pathspec)
                        copy_pathspec(&p->pathspec, pathspec);
@@ -139,8 +131,10 @@ void preload_index(struct index_state *index,
                if (pd.progress)
                        p->progress = &pd;
                offset += work;
-               if (pthread_create(&p->pthread, NULL, preload_thread, p))
-                       die("unable to create threaded lstat");
+               err = pthread_create(&p->pthread, NULL, preload_thread, p);
+
+               if (err)
+                       die(_("unable to create threaded lstat: %s"), strerror(err));
        }
        for (i = 0; i < threads; i++) {
                struct thread_data *p = data+i;
@@ -151,7 +145,6 @@ void preload_index(struct index_state *index,
 
        trace_performance_leave("preload index");
 }
-#endif
 
 int read_index_preload(struct index_state *index,
                       const struct pathspec *pathspec,
index 8c92450..4ca8128 100644 (file)
@@ -1752,7 +1752,7 @@ static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,
        size_t len;
        const char *name;
        unsigned int flags;
-       size_t copy_len;
+       size_t copy_len = 0;
        /*
         * Adjacent cache entries tend to share the leading paths, so it makes
         * sense to only store the differences in later entries.  In the v4
@@ -1792,8 +1792,6 @@ static struct cache_entry *create_from_disk(struct mem_pool *ce_mem_pool,
                                die(_("malformed name field in the index, near path '%s'"),
                                        previous_ce->name);
                        copy_len = previous_len - strip_len;
-               } else {
-                       copy_len = 0;
                }
                name = (const char *)cp;
        }
@@ -1926,19 +1924,15 @@ struct index_entry_offset_table
        struct index_entry_offset entries[FLEX_ARRAY];
 };
 
-#ifndef NO_PTHREADS
 static struct index_entry_offset_table *read_ieot_extension(const char *mmap, size_t mmap_size, size_t offset);
 static void write_ieot_extension(struct strbuf *sb, struct index_entry_offset_table *ieot);
-#endif
 
 static size_t read_eoie_extension(const char *mmap, size_t mmap_size);
 static void write_eoie_extension(struct strbuf *sb, git_hash_ctx *eoie_context, size_t offset);
 
 struct load_index_extensions
 {
-#ifndef NO_PTHREADS
        pthread_t pthread;
-#endif
        struct index_state *istate;
        const char *mmap;
        size_t mmap_size;
@@ -2016,8 +2010,6 @@ static unsigned long load_all_cache_entries(struct index_state *istate,
        return consumed;
 }
 
-#ifndef NO_PTHREADS
-
 /*
  * Mostly randomly chosen maximum thread counts: we
  * cap the parallelism to online_cpus() threads, and we want
@@ -2128,7 +2120,6 @@ static unsigned long load_cache_entries_threaded(struct index_state *istate, con
 
        return consumed;
 }
-#endif
 
 /* remember to discard_cache() before reading a different cache! */
 int do_read_index(struct index_state *istate, const char *path, int must_exist)
@@ -2141,10 +2132,8 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
        size_t mmap_size;
        struct load_index_extensions p;
        size_t extension_offset = 0;
-#ifndef NO_PTHREADS
        int nr_threads, cpus;
        struct index_entry_offset_table *ieot = NULL;
-#endif
 
        if (istate->initialized)
                return istate->cache_nr;
@@ -2187,7 +2176,6 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
 
        src_offset = sizeof(*hdr);
 
-#ifndef NO_PTHREADS
        nr_threads = git_config_get_index_threads();
 
        /* TODO: does creating more threads than cores help? */
@@ -2198,6 +2186,9 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
                        nr_threads = cpus;
        }
 
+       if (!HAVE_THREADS)
+               nr_threads = 1;
+
        if (nr_threads > 1) {
                extension_offset = read_eoie_extension(mmap, mmap_size);
                if (extension_offset) {
@@ -2225,22 +2216,16 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
        } else {
                src_offset += load_all_cache_entries(istate, mmap, mmap_size, src_offset);
        }
-#else
-       src_offset += load_all_cache_entries(istate, mmap, mmap_size, src_offset);
-#endif
 
        istate->timestamp.sec = st.st_mtime;
        istate->timestamp.nsec = ST_MTIME_NSEC(st);
 
        /* if we created a thread, join it otherwise load the extensions on the primary thread */
-#ifndef NO_PTHREADS
        if (extension_offset) {
                int ret = pthread_join(p.pthread, NULL);
                if (ret)
                        die(_("unable to join load_index_extensions thread: %s"), strerror(ret));
-       }
-#endif
-       if (!extension_offset) {
+       } else {
                p.src_offset = src_offset;
                load_index_extensions(&p);
        }
@@ -2762,8 +2747,11 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
        if (ce_write(&c, newfd, &hdr, sizeof(hdr)) < 0)
                return -1;
 
-#ifndef NO_PTHREADS
-       nr_threads = git_config_get_index_threads();
+       if (HAVE_THREADS)
+               nr_threads = git_config_get_index_threads();
+       else
+               nr_threads = 1;
+
        if (nr_threads != 1) {
                int ieot_blocks, cpus;
 
@@ -2793,7 +2781,6 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
                        ieot_entries = DIV_ROUND_UP(entries, ieot_blocks);
                }
        }
-#endif
 
        offset = lseek(newfd, 0, SEEK_CUR);
        if (offset < 0) {
@@ -2877,7 +2864,6 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
         * strip_extensions parameter as we need it when loading the shared
         * index.
         */
-#ifndef NO_PTHREADS
        if (ieot) {
                struct strbuf sb = STRBUF_INIT;
 
@@ -2889,7 +2875,6 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
                if (err)
                        return -1;
        }
-#endif
 
        if (!strip_extensions && istate->split_index) {
                struct strbuf sb = STRBUF_INIT;
@@ -3475,7 +3460,6 @@ static void write_eoie_extension(struct strbuf *sb, git_hash_ctx *eoie_context,
        strbuf_add(sb, hash, the_hash_algo->rawsz);
 }
 
-#ifndef NO_PTHREADS
 #define IEOT_VERSION   (1)
 
 static struct index_entry_offset_table *read_ieot_extension(const char *mmap, size_t mmap_size, size_t offset)
@@ -3548,4 +3532,3 @@ static void write_ieot_extension(struct strbuf *sb, struct index_entry_offset_ta
               strbuf_add(sb, &buffer, sizeof(uint32_t));
        }
 }
-#endif
index d679cc2..c11ff80 100644 (file)
@@ -1226,7 +1226,7 @@ int start_async(struct async *async)
        {
                int err = pthread_create(&async->tid, NULL, run_thread, async);
                if (err) {
-                       error_errno("cannot create thread");
+                       error(_("cannot create async thread: %s"), strerror(err));
                        goto error;
                }
        }
@@ -1259,6 +1259,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;
index 3932420..68f5369 100644 (file)
@@ -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);
 
 /**
index e920ca5..f692686 100644 (file)
@@ -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;
index a2135e0..5329845 100644 (file)
@@ -20,6 +20,9 @@
 
 int online_cpus(void)
 {
+#ifdef NO_PTHREADS
+       return 1;
+#else
 #ifdef _SC_NPROCESSORS_ONLN
        long ncpus;
 #endif
@@ -59,10 +62,12 @@ int online_cpus(void)
 #endif
 
        return 1;
+#endif
 }
 
 int init_recursive_mutex(pthread_mutex_t *m)
 {
+#ifndef NO_PTHREADS
        pthread_mutexattr_t a;
        int ret;
 
@@ -74,4 +79,47 @@ int init_recursive_mutex(pthread_mutex_t *m)
                pthread_mutexattr_destroy(&a);
        }
        return ret;
+#else
+       return 0;
+#endif
+}
+
+#ifdef NO_PTHREADS
+int dummy_pthread_create(pthread_t *pthread, const void *attr,
+                        void *(*fn)(void *), void *data)
+{
+       /*
+        * Do nothing.
+        *
+        * The main purpose of this function is to break compiler's
+        * flow analysis and avoid -Wunused-variable false warnings.
+        */
+       return ENOSYS;
+}
+
+int dummy_pthread_init(void *data)
+{
+       /*
+        * Do nothing.
+        *
+        * The main purpose of this function is to break compiler's
+        * flow analysis or it may realize that functions like
+        * pthread_mutex_init() is no-op, which means the (static)
+        * variable is not used/initialized at all and trigger
+        * -Wunused-variable
+        */
+       return ENOSYS;
 }
+
+int dummy_pthread_join(pthread_t pthread, void **retval)
+{
+       /*
+        * Do nothing.
+        *
+        * The main purpose of this function is to break compiler's
+        * flow analysis and avoid -Wunused-variable false warnings.
+        */
+       return ENOSYS;
+}
+
+#endif
index d9a769d..4961487 100644 (file)
@@ -4,12 +4,54 @@
 #ifndef NO_PTHREADS
 #include <pthread.h>
 
-extern int online_cpus(void);
-extern int init_recursive_mutex(pthread_mutex_t*);
+#define HAVE_THREADS 1
 
 #else
 
-#define online_cpus() 1
+#define HAVE_THREADS 0
+
+/*
+ * macros instead of typedefs because pthread definitions may have
+ * been pulled in by some system dependencies even though the user
+ * wants to disable pthread.
+ */
+#define pthread_t int
+#define pthread_mutex_t int
+#define pthread_cond_t int
+#define pthread_key_t int
+
+#define pthread_mutex_init(mutex, attr) dummy_pthread_init(mutex)
+#define pthread_mutex_lock(mutex)
+#define pthread_mutex_unlock(mutex)
+#define pthread_mutex_destroy(mutex)
+
+#define pthread_cond_init(cond, attr) dummy_pthread_init(cond)
+#define pthread_cond_wait(cond, mutex)
+#define pthread_cond_signal(cond)
+#define pthread_cond_broadcast(cond)
+#define pthread_cond_destroy(cond)
+
+#define pthread_key_create(key, attr) dummy_pthread_init(key)
+#define pthread_key_delete(key)
+
+#define pthread_create(thread, attr, fn, data) \
+       dummy_pthread_create(thread, attr, fn, data)
+#define pthread_join(thread, retval) \
+       dummy_pthread_join(thread, retval)
+
+#define pthread_setspecific(key, data)
+#define pthread_getspecific(key) NULL
+
+int dummy_pthread_create(pthread_t *pthread, const void *attr,
+                        void *(*fn)(void *), void *data);
+int dummy_pthread_join(pthread_t pthread, void **retval);
+
+int dummy_pthread_init(void *);
 
 #endif
+
+int online_cpus(void);
+int init_recursive_mutex(pthread_mutex_t*);
+
+
 #endif /* THREAD_COMPAT_H */