[ovs-dev] [PATCH 5/7] lib/cmap: Return number of nodes from functions modifying the cmap.

Jarno Rajahalme jrajahalme at nicira.com
Wed Oct 1 23:02:35 UTC 2014


We already update the count field as the last step of these functions,
so returning the current count is very cheap.  Callers that care about
the count become a bit more efficient, as they avoid extra
non-inlineable function call.

Signed-off-by: Jarno Rajahalme <jrajahalme at nicira.com>
---
 lib/cmap.c |   25 ++++++++-----------------
 lib/cmap.h |   24 +++++++++++++++++++-----
 2 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/lib/cmap.c b/lib/cmap.c
index db2b4a4..50eccbf 100644
--- a/lib/cmap.c
+++ b/lib/cmap.c
@@ -655,7 +655,7 @@ cmap_try_insert(struct cmap_impl *impl, struct cmap_node *node, uint32_t hash)
  * that 'cmap' cannot change concurrently (from another thread).  If duplicates
  * are undesirable, the caller must have already verified that 'cmap' does not
  * contain a duplicate of 'node'. */
-void
+size_t
 cmap_insert(struct cmap *cmap, struct cmap_node *node, uint32_t hash)
 {
     struct cmap_impl *impl = cmap_get_impl(cmap);
@@ -669,7 +669,7 @@ cmap_insert(struct cmap *cmap, struct cmap_node *node, uint32_t hash)
     while (OVS_UNLIKELY(!cmap_try_insert(impl, node, hash))) {
         impl = cmap_rehash(cmap, impl->mask);
     }
-    impl->n++;
+    return ++impl->n;
 }
 
 static bool
@@ -705,20 +705,6 @@ cmap_replace__(struct cmap_impl *impl, struct cmap_node *node,
     }
 }
 
-/* Removes 'node' from 'cmap'.  The caller must ensure that 'cmap' cannot
- * change concurrently (from another thread).
- *
- * 'node' must not be destroyed or modified or inserted back into 'cmap' or
- * into any other concurrent hash map while any other thread might be accessing
- * it.  One correct way to do this is to free it from an RCU callback with
- * ovsrcu_postpone(). */
-void
-cmap_remove(struct cmap *cmap, struct cmap_node *node, uint32_t hash)
-{
-    cmap_replace(cmap, node, NULL, hash);
-    cmap_get_impl(cmap)->n--;
-}
-
 /* Replaces 'old_node' in 'cmap' with 'new_node'.  The caller must
  * ensure that 'cmap' cannot change concurrently (from another thread).
  *
@@ -726,7 +712,7 @@ cmap_remove(struct cmap *cmap, struct cmap_node *node, uint32_t hash)
  * into any other concurrent hash map while any other thread might be accessing
  * it.  One correct way to do this is to free it from an RCU callback with
  * ovsrcu_postpone(). */
-void
+size_t
 cmap_replace(struct cmap *cmap, struct cmap_node *old_node,
              struct cmap_node *new_node, uint32_t hash)
 {
@@ -738,6 +724,11 @@ cmap_replace(struct cmap *cmap, struct cmap_node *old_node,
     ok = cmap_replace__(impl, old_node, new_node, hash, h1)
         || cmap_replace__(impl, old_node, new_node, hash, h2);
     ovs_assert(ok);
+
+    if (!new_node) {
+        impl->n--;
+    }
+    return impl->n;
 }
 
 static bool
diff --git a/lib/cmap.h b/lib/cmap.h
index 793202d..5fc7ead 100644
--- a/lib/cmap.h
+++ b/lib/cmap.h
@@ -87,11 +87,12 @@ void cmap_destroy(struct cmap *);
 size_t cmap_count(const struct cmap *);
 bool cmap_is_empty(const struct cmap *);
 
-/* Insertion and deletion. */
-void cmap_insert(struct cmap *, struct cmap_node *, uint32_t hash);
-void cmap_remove(struct cmap *, struct cmap_node *, uint32_t hash);
-void cmap_replace(struct cmap *, struct cmap_node *old_node,
-                  struct cmap_node *new_node, uint32_t hash);
+/* Insertion and deletion.  Return the current count after the operation. */
+size_t cmap_insert(struct cmap *, struct cmap_node *, uint32_t hash);
+static inline size_t cmap_remove(struct cmap *, struct cmap_node *,
+                                 uint32_t hash);
+size_t cmap_replace(struct cmap *, struct cmap_node *old_node,
+                    struct cmap_node *new_node, uint32_t hash);
 
 /* Search.
  *
@@ -225,4 +226,17 @@ cmap_first(const struct cmap *cmap)
     return cmap_next_position(cmap, &pos);
 }
 
+/* Removes 'node' from 'cmap'.  The caller must ensure that 'cmap' cannot
+ * change concurrently (from another thread).
+ *
+ * 'node' must not be destroyed or modified or inserted back into 'cmap' or
+ * into any other concurrent hash map while any other thread might be accessing
+ * it.  One correct way to do this is to free it from an RCU callback with
+ * ovsrcu_postpone(). */
+static inline size_t
+cmap_remove(struct cmap *cmap, struct cmap_node *node, uint32_t hash)
+{
+    return cmap_replace(cmap, node, NULL, hash);
+}
+
 #endif /* cmap.h */
-- 
1.7.10.4




More information about the dev mailing list