Standard C11 doesn't need these functions because it is able to require
implementations not to need them.  But we can't construct a portable
implementation that does not need them in every case, so this commit adds
them.

These functions are only needed for atomic_flag objects that are
dynamically allocated (because statically allocated objects can use
ATOMIC_FLAG_INIT).  So far there aren't any of those, but an upcoming
commit will introduce one.

Signed-off-by: Ben Pfaff <b...@nicira.com>
---
 lib/ovs-atomic-c11.h          |   12 ++++++++++++
 lib/ovs-atomic-flag-gcc4.7+.h |   12 ++++++++++++
 lib/ovs-atomic-pthreads.c     |   16 ++++++++++++++++
 lib/ovs-atomic-pthreads.h     |    3 +++
 lib/ovs-atomic.h              |   22 ++++++++++++++++++++++
 5 files changed, 65 insertions(+)

diff --git a/lib/ovs-atomic-c11.h b/lib/ovs-atomic-c11.h
index 9dc687c..97262b2 100644
--- a/lib/ovs-atomic-c11.h
+++ b/lib/ovs-atomic-c11.h
@@ -60,3 +60,15 @@ typedef _Atomic(int64_t)   atomic_int64_t;
     (*(ORIG) = atomic_fetch_xor_explicit(RMW, ARG, ORDER), (void) 0)
 #define atomic_and_explicit(RMW, ARG, ORIG, ORDER) \
     (*(ORIG) = atomic_fetch_and_explicit(RMW, ARG, ORDER), (void) 0)
+
+static inline void
+atomic_flag_init(volatile atomic_flag *object OVS_UNUSED)
+{
+    /* Nothing to do. */
+}
+
+static inline void
+atomic_flag_destroy(volatile atomic_flag *object OVS_UNUSED)
+{
+    /* Nothing to do. */
+}
diff --git a/lib/ovs-atomic-flag-gcc4.7+.h b/lib/ovs-atomic-flag-gcc4.7+.h
index c42c7ca..385d0de 100644
--- a/lib/ovs-atomic-flag-gcc4.7+.h
+++ b/lib/ovs-atomic-flag-gcc4.7+.h
@@ -26,6 +26,18 @@ typedef struct {
 } atomic_flag;
 #define ATOMIC_FLAG_INIT { .b = false }
 
+static inline void
+atomic_flag_init(volatile atomic_flag *object OVS_UNUSED)
+{
+    /* Nothing to do. */
+}
+
+static inline void
+atomic_flag_destroy(volatile atomic_flag *object OVS_UNUSED)
+{
+    /* Nothing to do. */
+}
+
 static inline bool
 atomic_flag_test_and_set_explicit(volatile atomic_flag *object,
                                   memory_order order)
diff --git a/lib/ovs-atomic-pthreads.c b/lib/ovs-atomic-pthreads.c
index a501b82..4b3a337 100644
--- a/lib/ovs-atomic-pthreads.c
+++ b/lib/ovs-atomic-pthreads.c
@@ -20,6 +20,22 @@
 #include "ovs-thread.h"
 
 #if OVS_ATOMIC_PTHREADS_IMPL
+void
+atomic_flag_init(volatile atomic_flag *flag_)
+{
+    atomic_flag *flag = CONST_CAST(atomic_flag *, flag_);
+
+    pthread_mutex_init(&flag->mutex, NULL);
+}
+
+void
+atomic_flag_destroy(volatile atomic_flag *flag_)
+{
+    atomic_flag *flag = CONST_CAST(atomic_flag *, flag_);
+
+    pthread_mutex_destroy(&flag->mutex);
+}
+
 bool
 atomic_flag_test_and_set(volatile atomic_flag *flag_)
 {
diff --git a/lib/ovs-atomic-pthreads.h b/lib/ovs-atomic-pthreads.h
index 2f47a9c..840c7a6 100644
--- a/lib/ovs-atomic-pthreads.h
+++ b/lib/ovs-atomic-pthreads.h
@@ -148,6 +148,9 @@ typedef struct {
 } atomic_flag;
 #define ATOMIC_FLAG_INIT { false, PTHREAD_MUTEX_INITIALIZER }
 
+void atomic_flag_init(volatile atomic_flag *);
+void atomic_flag_destroy(volatile atomic_flag *);
+
 bool atomic_flag_test_and_set(volatile atomic_flag *);
 bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order);
 
diff --git a/lib/ovs-atomic.h b/lib/ovs-atomic.h
index a9ae4ae..e714114 100644
--- a/lib/ovs-atomic.h
+++ b/lib/ovs-atomic.h
@@ -204,9 +204,31 @@
  * atomic_flag is a typedef for a type with two states, set and clear, that
  * provides atomic test-and-set functionality.
  *
+ *
+ * Life Cycle
+ * ----------
+ *
  * ATOMIC_FLAG_INIT is an initializer for atomic_flag.  The initial state is
  * "clear".
  *
+ * C11 does not have an initialization or destruction function for atomic_flag,
+ * because implementations should not need one (one may simply
+ * atomic_flag_clear() an uninitialized atomic_flag), but some implementations
+ * of the OVS atomics do need them.  Thus, the following two functions are
+ * provided for initializing and destroying non-static atomic_flags:
+ *
+ *     void atomic_flag_init(volatile atomic_flag *object);
+ *
+ *         Initializes 'object'.  The initial state is "clear".
+ *
+ *     void atomic_flag_destroy(volatile atomic_flag *object);
+ *
+ *         Destroys 'object'.
+ *
+ *
+ * Operations
+ * ----------
+ *
  * The following functions are available.
  *
  *     bool atomic_flag_test_and_set(atomic_flag *object)
-- 
1.7.10.4

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to