[4.1] 4b48aaf Barriers can be cyclic but not like semaphores
Lasse Karstensen
lkarsten at varnish-software.com
Tue Jun 14 11:19:08 CEST 2016
commit 4b48aaf9375cf494cb8e3d90076742fdee3dc9c8
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