[ovs-dev] [PATCH] seq: Add some comments.

Ben Pfaff blp at nicira.com
Mon Aug 12 20:45:33 UTC 2013


Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 lib/seq.c |   12 ++++++++++--
 lib/seq.h |   40 +++++++++++++++++++++++++++++++++++++++-
 2 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/lib/seq.c b/lib/seq.c
index abe1ad8..36e5065 100644
--- a/lib/seq.c
+++ b/lib/seq.c
@@ -106,7 +106,11 @@ seq_change(struct seq *seq)
     ovs_mutex_unlock(&seq_mutex);
 }
 
-/* Returns 'seq''s current sequence number (which could change immediately). */
+/* Returns 'seq''s current sequence number (which could change immediately).
+ *
+ * seq_read() and seq_wait() can be used together to yield a race-free wakeup
+ * when an object changes, even without an ability to lock the object.  See
+ * Usage in seq.h for details. */
 uint64_t
 seq_read(const struct seq *seq)
     OVS_EXCLUDED(seq_mutex)
@@ -156,7 +160,11 @@ seq_wait__(struct seq *seq, uint64_t value)
 
 /* Causes the following poll_block() to wake up when 'seq''s sequence number
  * changes from 'value'.  (If 'seq''s sequence number isn't 'value', then
- * poll_block() won't block at all.) */
+ * poll_block() won't block at all.)
+ *
+ * seq_read() and seq_wait() can be used together to yield a race-free wakeup
+ * when an object changes, even without an ability to lock the object.  See
+ * Usage in seq.h for details. */
 void
 seq_wait(const struct seq *seq_, uint64_t value)
     OVS_EXCLUDED(seq_mutex)
diff --git a/lib/seq.h b/lib/seq.h
index 3423e21..c764809 100644
--- a/lib/seq.h
+++ b/lib/seq.h
@@ -20,7 +20,7 @@
 /* Thread-safe, pollable sequence number.
  *
  *
- * Background
+ * Motivation
  * ==========
  *
  * It is sometimes desirable to take an action whenever an object changes.
@@ -66,6 +66,44 @@
  *    poll_block();
  *
  *
+ * Alternate Usage
+ * ===============
+ *
+ * struct seq can also be used as a sort of pollable condition variable.
+ * Suppose that we want a thread to process items in a queue, and thus to be
+ * able to wake up whenever the queue is nonempty.  This requires a lock to
+ * protect the queue and a seq to signal that the queue has become nonempty,
+ * e.g.:
+ *
+ *    struct ovs_mutex mutex;
+ *    struct list queue OVS_GUARDED_BY(mutex);
+ *    struct seq nonempty_seq;
+ *
+ * To add an element to the queue:
+ *
+ *    ovs_mutex_lock(&mutex);
+ *    list_push_back(&queue, ...element...);
+ *    if (list_is_singleton(&queue)) {   // The 'if' test here is optional.
+ *        seq_change(&nonempty_seq);
+ *    }
+ *    ovs_mutex_unlock(&mutex);
+ *
+ * To wait for the queue to become nonempty:
+ *
+ *    ovs_mutex_lock(&mutex);
+ *    if (list_is_empty(&queue)) {
+ *        seq_wait(&nonempty_seq, seq_read(&nonempty_seq));
+ *    } else {
+ *        poll_immediate_wake();
+ *    }
+ *    ovs_mutex_unlock(&mutex);
+ *
+ * (In the above code 'mutex' prevents the queue from changing between
+ * seq_read() and seq_wait().  Otherwise, it would be necessary to seq_read(),
+ * check for a nonempty queue, and then seq_wait() on the previously read
+ * sequence number, as under Usage above.)
+ *
+ *
  * Thread-safety
  * =============
  *
-- 
1.7.10.4




More information about the dev mailing list