ovs-atomic: Add atomic_destroy() and use everywhere it is needed.
authorBen Pfaff <blp@nicira.com>
Wed, 8 Jan 2014 18:42:12 +0000 (10:42 -0800)
committerBen Pfaff <blp@nicira.com>
Thu, 9 Jan 2014 01:13:30 +0000 (17:13 -0800)
C11 is able to require that atomics don't need to be destroyed, but some
of the OVS implementations do.

Signed-off-by: Ben Pfaff <blp@nicira.com>
18 files changed:
lib/bfd.c
lib/cfm.c
lib/lacp.c
lib/mac-learning.c
lib/netdev.c
lib/ovs-atomic-clang.h
lib/ovs-atomic-gcc4+.h
lib/ovs-atomic-gcc4.7+.h
lib/ovs-atomic-pthreads.h
lib/ovs-atomic.h
lib/stp.c
ofproto/bond.c
ofproto/netflow.c
ofproto/ofproto-dpif-ipfix.c
ofproto/ofproto-dpif-sflow.c
ofproto/ofproto-dpif-upcall.c
ofproto/ofproto.c
tests/test-atomic.c

index b8574d5..ad2d753 100644 (file)
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -460,6 +460,7 @@ bfd_unref(struct bfd *bfd) OVS_EXCLUDED(mutex)
             hmap_remove(all_bfds, &bfd->node);
             netdev_close(bfd->netdev);
             free(bfd->name);
+            atomic_destroy(&bfd->ref_cnt);
             free(bfd);
             ovs_mutex_unlock(&mutex);
         }
index 5ee94d5..fc0ef78 100644 (file)
--- a/lib/cfm.c
+++ b/lib/cfm.c
@@ -374,6 +374,11 @@ cfm_unref(struct cfm *cfm) OVS_EXCLUDED(mutex)
     hmap_destroy(&cfm->remote_mps);
     netdev_close(cfm->netdev);
     free(cfm->rmps_array);
+
+    atomic_destroy(&cfm->extended);
+    atomic_destroy(&cfm->check_tnl_key);
+    atomic_destroy(&cfm->ref_cnt);
+
     free(cfm);
 }
 
index 9eec1f9..2c17e22 100644 (file)
@@ -259,6 +259,7 @@ lacp_unref(struct lacp *lacp) OVS_EXCLUDED(mutex)
         hmap_destroy(&lacp->slaves);
         list_remove(&lacp->node);
         free(lacp->name);
+        atomic_destroy(&lacp->ref_cnt);
         free(lacp);
         ovs_mutex_unlock(&mutex);
     }
index c9c1ae9..f540d6d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -151,6 +151,7 @@ mac_learning_unref(struct mac_learning *ml)
 
         bitmap_free(ml->flood_vlans);
         ovs_rwlock_destroy(&ml->rwlock);
+        atomic_destroy(&ml->ref_cnt);
         free(ml);
     }
 }
index 1bcd80f..575227c 100644 (file)
@@ -224,6 +224,7 @@ netdev_unregister_provider(const char *type)
         atomic_read(&rc->ref_cnt, &ref_cnt);
         if (!ref_cnt) {
             hmap_remove(&netdev_classes, &rc->hmap_node);
+            atomic_destroy(&rc->ref_cnt);
             free(rc);
             error = 0;
         } else {
index dbec956..7449428 100644 (file)
@@ -63,6 +63,7 @@ typedef _Atomic(int64_t)   atomic_int64_t;
 #define ATOMIC_VAR_INIT(VALUE) (VALUE)
 
 #define atomic_init(OBJECT, VALUE) __c11_atomic_init(OBJECT, VALUE)
+#define atomic_destroy(OBJECT) ((void) (OBJECT))
 
 /* Clang hard-codes these exact values internally but does not appear to
  * export any names for them. */
index 4938261..b465181 100644 (file)
@@ -150,6 +150,7 @@ int64_t locked_int64_and(struct locked_int64 *, int64_t arg);
 \f
 #define ATOMIC_VAR_INIT(VALUE) { .value = (VALUE) }
 #define atomic_init(OBJECT, VALUE) ((OBJECT)->value = (VALUE), (void) 0)
+#define atomic_destroy(OBJECT) ((void) (OBJECT))
 
 static inline void
 atomic_thread_fence(memory_order order)
index 52e167f..56d265f 100644 (file)
@@ -71,6 +71,7 @@ typedef enum {
 
 #define ATOMIC_VAR_INIT(VALUE) (VALUE)
 #define atomic_init(OBJECT, VALUE) (*(OBJECT) = (VALUE), (void) 0)
+#define atomic_destroy(OBJECT) ((void) (OBJECT))
 
 #define atomic_thread_fence __atomic_thread_fence
 #define atomic_signal_fence __atomic_signal_fence
index 840c7a6..dc8f498 100644 (file)
@@ -85,6 +85,9 @@ typedef enum {
     ((OBJECT)->value = (VALUE),                         \
      pthread_mutex_init(&(OBJECT)->mutex, NULL),        \
      (void) 0)
+#define atomic_destroy(OBJECT)                  \
+    (pthread_mutex_destroy(&(OBJECT)->mutex),   \
+     (void) 0)
 
 static inline void
 atomic_thread_fence(memory_order order OVS_UNUSED)
index e714114..2c07138 100644 (file)
@@ -84,8 +84,8 @@
  * that.
  *
  *
- * Initialization
- * ==============
+ * Life Cycle
+ * ==========
  *
  * To initialize an atomic variable at its point of definition, use
  * ATOMIC_VAR_INIT:
  * ...
  *     atomic_init(&ai, 123);
  *
+ * C11 does not hav an destruction function for atomic types, but some
+ * implementations of the OVS atomics do need them.  Thus, the following
+ * function is provided for destroying non-static atomic objects (A is any
+ * atomic type):
+ *
+ *     void atomic_destroy(A *object);
+ *
+ *         Destroys 'object'.
+ *
  *
  * Barriers
  * ========
index 8140263..818f2ca 100644 (file)
--- a/lib/stp.c
+++ b/lib/stp.c
@@ -342,6 +342,7 @@ stp_unref(struct stp *stp)
         list_remove(&stp->node);
         ovs_mutex_unlock(&mutex);
         free(stp->name);
+        atomic_destroy(&stp->ref_cnt);
         free(stp);
     }
 }
index ff050f1..3b0c11c 100644 (file)
@@ -231,6 +231,7 @@ bond_unref(struct bond *bond)
 
     free(bond->hash);
     free(bond->name);
+    atomic_destroy(&bond->ref_cnt);
     free(bond);
 }
 
index f79ad6a..3aa0630 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, 2010, 2011 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -438,6 +438,7 @@ netflow_unref(struct netflow *nf)
         atomic_sub(&netflow_count, 1, &orig);
         collectors_destroy(nf->collectors);
         ofpbuf_uninit(&nf->packet);
+        atomic_destroy(&nf->ref_cnt);
         free(nf);
     }
 }
index a9cc73e..55544cc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Nicira, Inc.
+ * Copyright (c) 2012, 2013 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -696,6 +696,7 @@ dpif_ipfix_unref(struct dpif_ipfix *di) OVS_EXCLUDED(mutex)
         dpif_ipfix_clear(di);
         dpif_ipfix_bridge_exporter_destroy(&di->bridge_exporter);
         hmap_destroy(&di->flow_exporter_map);
+        atomic_destroy(&di->ref_cnt);
         free(di);
         ovs_mutex_unlock(&mutex);
     }
index 158887f..d45eada 100644 (file)
@@ -377,6 +377,7 @@ dpif_sflow_unref(struct dpif_sflow *ds) OVS_EXCLUDED(mutex)
             dpif_sflow_del_port__(ds, dsp);
         }
         hmap_destroy(&ds->ports);
+        atomic_destroy(&ds->ref_cnt);
         free(ds);
     }
 }
index 47a3abf..dd24f5c 100644 (file)
@@ -273,6 +273,8 @@ udpif_destroy(struct udpif *udpif)
     latch_destroy(&udpif->exit_latch);
     seq_destroy(udpif->reval_seq);
     seq_destroy(udpif->dump_seq);
+    atomic_destroy(&udpif->max_idle);
+    atomic_destroy(&udpif->flow_limit);
     free(udpif);
 }
 
index 676a6cb..f651374 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
  * Copyright (c) 2010 Jean Tourrilhes - HP-Labs.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -2578,6 +2578,7 @@ ofproto_rule_destroy__(struct rule *rule)
     cls_rule_destroy(CONST_CAST(struct cls_rule *, &rule->cr));
     rule_actions_unref(rule->actions);
     ovs_mutex_destroy(&rule->mutex);
+    atomic_destroy(&rule->ref_count);
     rule->ofproto->ofproto_class->rule_dealloc(rule);
 }
 
@@ -2625,6 +2626,7 @@ rule_actions_unref(struct rule_actions *actions)
 
         atomic_sub(&actions->ref_count, 1, &orig);
         if (orig == 1) {
+            atomic_destroy(&actions->ref_count);
             free(actions->ofpacts);
             free(actions);
         } else {
@@ -6665,6 +6667,7 @@ oftable_destroy(struct oftable *table)
     oftable_disable_eviction(table);
     classifier_destroy(&table->cls);
     free(table->name);
+    atomic_destroy(&table->config);
 }
 
 /* Changes the name of 'table' to 'name'.  If 'name' is NULL or the empty
index e6df1cd..bc00df1 100644 (file)
@@ -59,6 +59,8 @@
         ovs_assert(orig == 2);                          \
         atomic_read(&x, &value);                        \
         ovs_assert(value == 8);                         \
+                                                        \
+        atomic_destroy(&x);                             \
     }
 
 static void