[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