testsuite: Add timeout to add_of_br() command.
[cascardo/ovs.git] / lib / seq.h
index 3423e21..b0ec6bf 100644 (file)
--- a/lib/seq.h
+++ b/lib/seq.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013 Nicira, Inc.
+ * Copyright (c) 2013, 2014 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@
 /* Thread-safe, pollable sequence number.
  *
  *
- * Background
+ * Motivation
  * ==========
  *
  * It is sometimes desirable to take an action whenever an object changes.
  *    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 ovs_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
  * =============
  *
- * 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>
+#include "util.h"
 
 /* For implementation of an object with a sequence number attached. */
 struct seq *seq_create(void);
@@ -81,7 +124,9 @@ void seq_change(struct seq *);
 
 /* For observers. */
 uint64_t seq_read(const struct seq *);
-void seq_wait(const struct seq *, uint64_t value);
+
+void seq_wait_at(const struct seq *, uint64_t value, const char *where);
+#define seq_wait(seq, value) seq_wait_at(seq, value, OVS_SOURCE_LOCATOR)
 
 /* For poll_block() internal use. */
 void seq_woke(void);