index-pack: protect deepest_delta in multithread code

deepest_delta is a global variable but is updated without protection in resolve_delta(), a multithreaded function. Add a new mutex for it, but only protect and update when it's actually used (i.e. show_stat is non-zero). Another variable that will not be updated is delta_depth in "struct object_entry" as it's only useful when show_stat is 1. Putting it in "if (show_stat)" makes it clearer. The local variable "stat" is renamed to "show_stat" after moving to global scope because the name "stat" conflicts with stat(2) syscall. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Reviewed-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Nguyễn Thái Ngọc Duy committed Mar 19, 2013 at 20:01 UTC 3aba2fddcbff6ba611c05eabeb4a8561c119275f
1 file changed +23 -7
builtin/index-pack.c
+23 -7
@@ -78,6 +78,7 @@ static int nr_threads;
78 static int from_stdin;
79 static int strict;
80 static int verbose;
81 +static int show_stat;
82
83 static struct progress *progress;
84
@@ -108,6 +109,10 @@ static pthread_mutex_t work_mutex;
109 #define work_lock() lock_mutex(&work_mutex)
110 #define work_unlock() unlock_mutex(&work_mutex)
111
112 +static pthread_mutex_t deepest_delta_mutex;
113 +#define deepest_delta_lock() lock_mutex(&deepest_delta_mutex)
114 +#define deepest_delta_unlock() unlock_mutex(&deepest_delta_mutex)
115 +
116 static pthread_key_t key;
117
118 static inline void lock_mutex(pthread_mutex_t *mutex)
@@ -130,6 +135,8 @@ static void init_thread(void)
135 init_recursive_mutex(&read_mutex);
136 pthread_mutex_init(&counter_mutex, NULL);
137 pthread_mutex_init(&work_mutex, NULL);
138 + if (show_stat)
139 + pthread_mutex_init(&deepest_delta_mutex, NULL);
140 pthread_key_create(&key, NULL);
141 thread_data = xcalloc(nr_threads, sizeof(*thread_data));
142 threads_active = 1;
@@ -143,6 +150,8 @@ static void cleanup_thread(void)
150 pthread_mutex_destroy(&read_mutex);
151 pthread_mutex_destroy(&counter_mutex);
152 pthread_mutex_destroy(&work_mutex);
153 + if (show_stat)
154 + pthread_mutex_destroy(&deepest_delta_mutex);
155 pthread_key_delete(key);
156 free(thread_data);
157 }
@@ -158,6 +167,9 @@ static void cleanup_thread(void)
167 #define work_lock()
168 #define work_unlock()
169
170 +#define deepest_delta_lock()
171 +#define deepest_delta_unlock()
172 +
173 #endif
174
175
@@ -833,9 +845,13 @@ static void resolve_delta(struct object_entry *delta_obj,
845 void *base_data, *delta_data;
846
847 delta_obj->real_type = base->obj->real_type;
836 - delta_obj->delta_depth = base->obj->delta_depth + 1;
837 - if (deepest_delta < delta_obj->delta_depth)
838 - deepest_delta = delta_obj->delta_depth;
848 + if (show_stat) {
849 + delta_obj->delta_depth = base->obj->delta_depth + 1;
850 + deepest_delta_lock();
851 + if (deepest_delta < delta_obj->delta_depth)
852 + deepest_delta = delta_obj->delta_depth;
853 + deepest_delta_unlock();
854 + }
855 delta_obj->base_object_no = base->obj - objects;
856 delta_data = get_data_from_pack(delta_obj);
857 base_data = get_base_data(base);
@@ -1461,7 +1477,7 @@ static void show_pack_info(int stat_only)
1477
1478 int cmd_index_pack(int argc, const char **argv, const char *prefix)
1479 {
1464 - int i, fix_thin_pack = 0, verify = 0, stat_only = 0, stat = 0;
1480 + int i, fix_thin_pack = 0, verify = 0, stat_only = 0;
1481 const char *curr_pack, *curr_index;
1482 const char *index_name = NULL, *pack_name = NULL;
1483 const char *keep_name = NULL, *keep_msg = NULL;
@@ -1494,10 +1510,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
1510 verify = 1;
1511 } else if (!strcmp(arg, "--verify-stat")) {
1512 verify = 1;
1497 - stat = 1;
1513 + show_stat = 1;
1514 } else if (!strcmp(arg, "--verify-stat-only")) {
1515 verify = 1;
1500 - stat = 1;
1516 + show_stat = 1;
1517 stat_only = 1;
1518 } else if (!strcmp(arg, "--keep")) {
1519 keep_msg = "";
@@ -1605,7 +1621,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
1621 if (strict)
1622 check_objects();
1623
1608 - if (stat)
1624 + if (show_stat)
1625 show_pack_info(stat_only);
1626
1627 idx_objects = xmalloc((nr_objects) * sizeof(struct pack_idx_entry *));