summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarno Rajahalme <jrajahalme@nicira.com>2014-08-29 16:15:44 -0700
committerJarno Rajahalme <jrajahalme@nicira.com>2014-08-29 16:15:44 -0700
commitab355e676375f6d7b6715f3fc4ac6b750b5df1bb (patch)
treec4f19df2c196ce256695d2ad9f3b52edc1a36b1f
parentdce96af8fd873ce1a2c451f511725fe1a28aebee (diff)
downloadopenvswitch-ab355e676375f6d7b6715f3fc4ac6b750b5df1bb.tar.gz
lib/seq: Document acquire-release semantics.
Seq objects would be really hard to use if they did not provide acquire-release semantics. Currently they do that via ovs_mutex_lock()/ovs_mutex_unlock(), respectively. Document the behavior so that it is safer to rely on that elsewhere. Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
-rw-r--r--lib/ovs-thread.c8
-rw-r--r--lib/seq.h6
2 files changed, 12 insertions, 2 deletions
diff --git a/lib/ovs-thread.c b/lib/ovs-thread.c
index efbd60f5f..6d352eace 100644
--- a/lib/ovs-thread.c
+++ b/lib/ovs-thread.c
@@ -278,7 +278,11 @@ ovs_barrier_destroy(struct ovs_barrier *barrier)
}
/* Makes the calling thread block on the 'barrier' until all
- * 'barrier->size' threads hit the barrier. */
+ * 'barrier->size' threads hit the barrier.
+ * ovs_barrier provides the necessary acquire-release semantics to make
+ * the effects of prior memory accesses of all the participating threads
+ * visible on return and to prevent the following memory accesses to be
+ * reordered before the ovs_barrier_block(). */
void
ovs_barrier_block(struct ovs_barrier *barrier)
{
@@ -288,6 +292,8 @@ ovs_barrier_block(struct ovs_barrier *barrier)
atomic_add(&barrier->count, 1, &orig);
if (orig + 1 == barrier->size) {
atomic_store(&barrier->count, 0);
+ /* seq_change() serves as a release barrier against the other threads,
+ * so the zeroed count is visible to them as they continue. */
seq_change(barrier->seq);
}
diff --git a/lib/seq.h b/lib/seq.h
index 38c0e5275..f15bc1be9 100644
--- a/lib/seq.h
+++ b/lib/seq.h
@@ -107,7 +107,11 @@
* Thread-safety
* =============
*
- * Fully thread safe.
+ * Fully thread safe. seq_change() synchronizes with seq_read() and
+ * seq_wait() on the same variable in release-acquire fashion. That
+ * is, all effects of the memory accesses performed by a thread prior
+ * to seq_change() are visible to the threads returning from
+ * seq_read() or seq_wait() observing that change.
*/
#include <stdint.h>