Thanks for the added comments. Looks good. Coding style says we should not use "//", but not sure if this applies to comments.
On Mon, Aug 12, 2013 at 1:45 PM, Ben Pfaff <b...@nicira.com> wrote: > Signed-off-by: Ben Pfaff <b...@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 > > _______________________________________________ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev >
_______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev