[PATCH 4/3] fix threaded delta search locking

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Found by Jeff King.

Signed-off-by: Nicolas Pitre <nico@xxxxxxx>
---

On Mon, 10 Sep 2007, Jeff King wrote:

> I think I am seeing something like this:
>  - thread A gets data_request lock
>  - thread A unlocks data_provider lock, signaling provider
>  - thread A blocks getting data_ready lock
>  - provider allocates work for A, unlocking data_ready to signal A
>  - provider unlocks data_request lock, ready for next request
>  - thread B gets data_request lock
>  - thread B unlocks data_provider lock, signaling provider
>  - thread B gets data_ready lock, because A still hasn't run yet
>  - thread B tries to run on bogus data, since provider hasn't actually
>    allocated any work yet

Doh!

OK I prefer the following fix as it doesn't need an additional lock.

Junio: you might fold this with patch 1/3 if you wish.


diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 42698d2..af12e45 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -1597,6 +1597,7 @@ static void *threaded_find_deltas(void *arg)
 		data_requester = me;
 		pthread_mutex_unlock(&data_provider);
 		pthread_mutex_lock(&data_ready);
+		pthread_mutex_unlock(&data_request);
 
 		if (!me->list_size)
 			return NULL;
@@ -1609,7 +1610,7 @@ static void *threaded_find_deltas(void *arg)
 static void ll_find_deltas(struct object_entry **list, unsigned list_size,
 			   int window, int depth, unsigned *processed)
 {
-	struct thread_params p[delta_search_threads];
+	struct thread_params *target, p[delta_search_threads];
 	int i, ret;
 	unsigned chunk_size;
 
@@ -1645,17 +1646,17 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size,
 			sublist_size++;
 
 		pthread_mutex_lock(&data_provider);
-		data_requester->list = list;
-		data_requester->list_size = sublist_size;
+		target = data_requester;
+		target->list = list;
+		target->list_size = sublist_size;
 		pthread_mutex_unlock(&data_ready);
 
 		list += sublist_size;
 		list_size -= sublist_size;
 		if (!sublist_size) {
-			pthread_join(data_requester->thread, NULL);
+			pthread_join(target->thread, NULL);
 			i--;
 		}
-		pthread_mutex_unlock(&data_request);
 	} while (i);
 }
 
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux