[master] 8942cea Barriers can be cyclic but not like semaphores

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Tue Mar 29 14:20:05 CEST 2016


commit 8942ceaa88f0f3600eca8de7a9bb3139dfc155b3
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Wed Dec 23 08:27:14 2015 +0100

    Barriers can be cyclic but not like semaphores
    
    This is useful in HTTP loops where it's impossible to predict and use an
    array of barriers. All cycles expect the same number of waiters, unlike
    semaphores.

diff --git a/bin/varnishtest/tests/a00008.vtc b/bin/varnishtest/tests/a00008.vtc
index 6fe35c9..dfa84d3 100644
--- a/bin/varnishtest/tests/a00008.vtc
+++ b/bin/varnishtest/tests/a00008.vtc
@@ -1,25 +1,30 @@
 varnishtest "Barrier operations"
 
-barrier b1 cond 4
-barrier b2 cond 4
+# bs -> server, bc -> client, bb -> both
+barrier bs cond 4
+barrier bc cond 4
+barrier bb cond 4 -cyclic
 
 server s1 {
 	rxreq
-	barrier b1 sync
+	barrier bs sync
+	barrier bb sync
 	delay .9
 	txresp
 } -start
 
 server s2 {
 	rxreq
-	barrier b1 sync
+	barrier bs sync
+	barrier bb sync
 	delay .6
 	txresp
 } -start
 
 server s3 {
 	rxreq
-	barrier b1 sync
+	barrier bs sync
+	barrier bb sync
 	delay .2
 	txresp
 } -start
@@ -28,25 +33,30 @@ client c1 -connect ${s1_sock} {
 	delay .2
 	txreq
 	rxresp
-	barrier b2 sync
+	barrier bc sync
+	barrier bb sync
 } -start
 
 client c2 -connect ${s2_sock} {
 	delay .6
 	txreq
 	rxresp
-	barrier b2 sync
+	barrier bc sync
+	barrier bb sync
 } -start
 
 client c3 -connect ${s3_sock} {
 	delay .9
 	txreq
 	rxresp
-	barrier b2 sync
+	barrier bc sync
+	barrier bb sync
 } -start
 
 # Wait for all servers to have received requests
-barrier b1 sync
+barrier bs sync
+barrier bb sync
 
 # Wait for all clients to have received responses
-barrier b2 sync
+barrier bc sync
+barrier bb sync
diff --git a/bin/varnishtest/vtc_barrier.c b/bin/varnishtest/vtc_barrier.c
index 448eb0d..b170c56 100644
--- a/bin/varnishtest/vtc_barrier.c
+++ b/bin/varnishtest/vtc_barrier.c
@@ -52,6 +52,7 @@ struct barrier {
 
 	unsigned		waiters;
 	unsigned		expected;
+	unsigned		cyclic;
 
 	enum barrier_e		type;
 };
@@ -122,6 +123,23 @@ barrier_sock(struct barrier *b, const char *av, struct vtclog *vl)
 	INCOMPL();
 }
 
+static void
+barrier_cyclic(struct barrier *b, struct vtclog *vl)
+{
+
+	CHECK_OBJ_NOTNULL(b, BARRIER_MAGIC);
+
+	if (b->type == BARRIER_NONE)
+		vtc_log(vl, 0,
+		    "Barrier(%s) use error: not initialized", b->name);
+
+	if (b->waiters != 0)
+		vtc_log(vl, 0,
+		    "Barrier(%s) use error: already in use", b->name);
+
+	b->cyclic = 1;
+}
+
 /**********************************************************************
  * Sync a barrier
  */
@@ -148,6 +166,9 @@ barrier_cond_sync(struct barrier *b, struct vtclog *vl)
 		    b->name, b->waiters, b->expected);
 		AZ(pthread_cond_wait(&b->cond, &b->mtx));
 	}
+
+	if (b->cyclic)
+		b->waiters = 0;
 }
 
 static void
@@ -189,7 +210,10 @@ cmd_barrier(CMD_ARGS)
 		VTAILQ_FOREACH_SAFE(b, &barriers, list, b2) {
 			AZ(pthread_mutex_lock(&b->mtx));
 			assert(b->type != BARRIER_NONE);
-			assert(b->waiters == b->expected);
+			if (b->cyclic)
+				AZ(b->waiters);
+			else
+				assert(b->waiters == b->expected);
 			AZ(pthread_mutex_unlock(&b->mtx));
 		}
 		AZ(pthread_mutex_unlock(&barrier_mtx));
@@ -226,6 +250,10 @@ cmd_barrier(CMD_ARGS)
 			barrier_sync(b, vl);
 			continue;
 		}
+		if (!strcmp(*av, "-cyclic")) {
+			barrier_cyclic(b, vl);
+			continue;
+		}
 		vtc_log(vl, 0, "Unknown barrier argument: %s", *av);
 	}
 	AZ(pthread_mutex_unlock(&b->mtx));



More information about the varnish-commit mailing list