Merge branch 'nd/index-pack-threaded-fixes' into maint
authorJunio C Hamano <gitster@pobox.com>
Thu, 4 Apr 2013 20:00:41 +0000 (13:00 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 4 Apr 2013 20:00:41 +0000 (13:00 -0700)
* nd/index-pack-threaded-fixes:
index-pack: guard nr_resolved_deltas reads by lock
index-pack: protect deepest_delta in multithread code

1  2 
builtin/index-pack.c
diff --combined builtin/index-pack.c
index 3a3051d53e03cfb51d7eb156356f158e11f64b10,fe63cff1ca64336d693304f0c73ca3c744915235..79dfe47320e244c3110ce65d5b19fa87ebca3cb5
@@@ -78,6 -78,7 +78,7 @@@ static int nr_threads
  static int from_stdin;
  static int strict;
  static int verbose;
+ static int show_stat;
  
  static struct progress *progress;
  
@@@ -108,6 -109,10 +109,10 @@@ static pthread_mutex_t work_mutex
  #define work_lock()           lock_mutex(&work_mutex)
  #define work_unlock()         unlock_mutex(&work_mutex)
  
+ static pthread_mutex_t deepest_delta_mutex;
+ #define deepest_delta_lock()  lock_mutex(&deepest_delta_mutex)
+ #define deepest_delta_unlock()        unlock_mutex(&deepest_delta_mutex)
  static pthread_key_t key;
  
  static inline void lock_mutex(pthread_mutex_t *mutex)
@@@ -130,6 -135,8 +135,8 @@@ static void init_thread(void
        init_recursive_mutex(&read_mutex);
        pthread_mutex_init(&counter_mutex, NULL);
        pthread_mutex_init(&work_mutex, NULL);
+       if (show_stat)
+               pthread_mutex_init(&deepest_delta_mutex, NULL);
        pthread_key_create(&key, NULL);
        thread_data = xcalloc(nr_threads, sizeof(*thread_data));
        threads_active = 1;
@@@ -143,6 -150,8 +150,8 @@@ static void cleanup_thread(void
        pthread_mutex_destroy(&read_mutex);
        pthread_mutex_destroy(&counter_mutex);
        pthread_mutex_destroy(&work_mutex);
+       if (show_stat)
+               pthread_mutex_destroy(&deepest_delta_mutex);
        pthread_key_delete(key);
        free(thread_data);
  }
  #define work_lock()
  #define work_unlock()
  
+ #define deepest_delta_lock()
+ #define deepest_delta_unlock()
  #endif
  
  
@@@ -291,7 -303,7 +303,7 @@@ static void parse_pack_header(void
        if (hdr->hdr_signature != htonl(PACK_SIGNATURE))
                die(_("pack signature mismatch"));
        if (!pack_version_ok(hdr->hdr_version))
 -              die("pack version %"PRIu32" unsupported",
 +              die(_("pack version %"PRIu32" unsupported"),
                        ntohl(hdr->hdr_version));
  
        nr_objects = ntohl(hdr->hdr_entries);
@@@ -833,9 -845,13 +845,13 @@@ static void resolve_delta(struct object
        void *base_data, *delta_data;
  
        delta_obj->real_type = base->obj->real_type;
-       delta_obj->delta_depth = base->obj->delta_depth + 1;
-       if (deepest_delta < delta_obj->delta_depth)
-               deepest_delta = delta_obj->delta_depth;
+       if (show_stat) {
+               delta_obj->delta_depth = base->obj->delta_depth + 1;
+               deepest_delta_lock();
+               if (deepest_delta < delta_obj->delta_depth)
+                       deepest_delta = delta_obj->delta_depth;
+               deepest_delta_unlock();
+       }
        delta_obj->base_object_no = base->obj - objects;
        delta_data = get_data_from_pack(delta_obj);
        base_data = get_base_data(base);
@@@ -951,8 -967,10 +967,10 @@@ static void *threaded_second_pass(void 
        set_thread_data(data);
        for (;;) {
                int i;
-               work_lock();
+               counter_lock();
                display_progress(progress, nr_resolved_deltas);
+               counter_unlock();
+               work_lock();
                while (nr_dispatched < nr_objects &&
                       is_delta_type(objects[nr_dispatched].type))
                        nr_dispatched++;
@@@ -1061,8 -1079,7 +1079,8 @@@ static void resolve_deltas(void
                        int ret = pthread_create(&thread_data[i].thread, NULL,
                                                 threaded_second_pass, thread_data + i);
                        if (ret)
 -                              die("unable to create thread: %s", strerror(ret));
 +                              die(_("unable to create thread: %s"),
 +                                  strerror(ret));
                }
                for (i = 0; i < nr_threads; i++)
                        pthread_join(thread_data[i].thread, NULL);
@@@ -1099,7 -1116,7 +1117,7 @@@ static void conclude_pack(int fix_thin_
        if (fix_thin_pack) {
                struct sha1file *f;
                unsigned char read_sha1[20], tail_sha1[20];
 -              char msg[48];
 +              struct strbuf msg = STRBUF_INIT;
                int nr_unresolved = nr_deltas - nr_resolved_deltas;
                int nr_objects_initial = nr_objects;
                if (nr_unresolved <= 0)
                objects = xrealloc(objects,
                                   (nr_objects + nr_unresolved + 1)
                                   * sizeof(*objects));
 +              memset(objects + nr_objects + 1, 0,
 +                     nr_unresolved * sizeof(*objects));
                f = sha1fd(output_fd, curr_pack);
                fix_unresolved_deltas(f, nr_unresolved);
 -              sprintf(msg, "completed with %d local objects",
 -                      nr_objects - nr_objects_initial);
 -              stop_progress_msg(&progress, msg);
 +              strbuf_addf(&msg, _("completed with %d local objects"),
 +                          nr_objects - nr_objects_initial);
 +              stop_progress_msg(&progress, msg.buf);
 +              strbuf_release(&msg);
                sha1close(f, tail_sha1, 0);
                hashcpy(read_sha1, pack_sha1);
                fixup_pack_header_footer(output_fd, pack_sha1,
                                         curr_pack, nr_objects,
                                         read_sha1, consumed_bytes-20);
                if (hashcmp(read_sha1, tail_sha1) != 0)
 -                      die("Unexpected tail checksum for %s "
 -                          "(disk corruption?)", curr_pack);
 +                      die(_("Unexpected tail checksum for %s "
 +                            "(disk corruption?)"), curr_pack);
        }
        if (nr_deltas != nr_resolved_deltas)
                die(Q_("pack has %d unresolved delta",
@@@ -1331,17 -1345,17 +1349,17 @@@ static int git_index_pack_config(const 
        if (!strcmp(k, "pack.indexversion")) {
                opts->version = git_config_int(k, v);
                if (opts->version > 2)
 -                      die("bad pack.indexversion=%"PRIu32, opts->version);
 +                      die(_("bad pack.indexversion=%"PRIu32), opts->version);
                return 0;
        }
        if (!strcmp(k, "pack.threads")) {
                nr_threads = git_config_int(k, v);
                if (nr_threads < 0)
 -                      die("invalid number of threads specified (%d)",
 +                      die(_("invalid number of threads specified (%d)"),
                            nr_threads);
  #ifdef NO_PTHREADS
                if (nr_threads != 1)
 -                      warning("no threads support, ignoring %s", k);
 +                      warning(_("no threads support, ignoring %s"), k);
                nr_threads = 1;
  #endif
                return 0;
@@@ -1465,7 -1479,7 +1483,7 @@@ static void show_pack_info(int stat_onl
  
  int cmd_index_pack(int argc, const char **argv, const char *prefix)
  {
-       int i, fix_thin_pack = 0, verify = 0, stat_only = 0, stat = 0;
+       int i, fix_thin_pack = 0, verify = 0, stat_only = 0;
        const char *curr_pack, *curr_index;
        const char *index_name = NULL, *pack_name = NULL;
        const char *keep_name = NULL, *keep_msg = NULL;
                                verify = 1;
                        } else if (!strcmp(arg, "--verify-stat")) {
                                verify = 1;
-                               stat = 1;
+                               show_stat = 1;
                        } else if (!strcmp(arg, "--verify-stat-only")) {
                                verify = 1;
-                               stat = 1;
+                               show_stat = 1;
                                stat_only = 1;
                        } else if (!strcmp(arg, "--keep")) {
                                keep_msg = "";
                                        usage(index_pack_usage);
  #ifdef NO_PTHREADS
                                if (nr_threads != 1)
 -                                      warning("no threads support, "
 -                                              "ignoring %s", arg);
 +                                      warning(_("no threads support, "
 +                                                "ignoring %s"), arg);
                                nr_threads = 1;
  #endif
                        } else if (!prefixcmp(arg, "--pack_header=")) {
        if (strict)
                check_objects();
  
-       if (stat)
+       if (show_stat)
                show_pack_info(stat_only);
  
        idx_objects = xmalloc((nr_objects) * sizeof(struct pack_idx_entry *));