diff options
author | Ben Pfaff <blp@nicira.com> | 2013-08-12 13:45:01 -0700 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2013-08-12 13:59:02 -0700 |
commit | 5d389d55c78a20bd18b68b35f0e6cabae2686dcb (patch) | |
tree | a3408972027b67f650f4b1c51916de681478eeb8 | |
parent | 5e1de67fa16019acac301dd410ead42833dc3256 (diff) | |
download | openvswitch-5d389d55c78a20bd18b68b35f0e6cabae2686dcb.tar.gz |
seq: Add some comments.
Signed-off-by: Ben Pfaff <blp@nicira.com>
-rw-r--r-- | lib/seq.c | 12 | ||||
-rw-r--r-- | lib/seq.h | 40 |
2 files changed, 49 insertions, 3 deletions
@@ -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) @@ -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 * ============= * |