[ovs-dev] [PATCH 01/22] id-pool: re-factor recirculation id allocator into stand-alone id pool

Simon Horman simon.horman at netronome.com
Mon Nov 10 04:47:48 UTC 2014


Refactor the lock-free portion of the recirculation id allocator
into stand-alone id pool. This is in preparation for re-using
that portion to allocate bucket ids which are part of (draft)
Open Flow 1.5 groups.

EXT-350
Signed-off-by: Simon Horman <simon.horman at netronome.com>
---
 lib/automake.mk            |   2 +
 lib/id-pool.c              | 152 +++++++++++++++++++++++++++++++++++++++++++++
 lib/id-pool.h              |  42 +++++++++++++
 ofproto/ofproto-dpif-rid.c | 128 ++------------------------------------
 4 files changed, 202 insertions(+), 122 deletions(-)
 create mode 100644 lib/id-pool.c
 create mode 100644 lib/id-pool.h

diff --git a/lib/automake.mk b/lib/automake.mk
index 1256af1..40c0241 100644
--- a/lib/automake.mk
+++ b/lib/automake.mk
@@ -84,6 +84,8 @@ lib_libopenvswitch_la_SOURCES = \
 	lib/hmap.h \
 	lib/hmapx.c \
 	lib/hmapx.h \
+	lib/id-pool.c \
+	lib/id-pool.h \
 	lib/jhash.c \
 	lib/jhash.h \
 	lib/json.c \
diff --git a/lib/id-pool.c b/lib/id-pool.c
new file mode 100644
index 0000000..e6d7827
--- /dev/null
+++ b/lib/id-pool.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2014 Nicira, Inc.
+ * Copyright (c) 2014 Netronome.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <config.h>
+
+#include "hmap.h"
+#include "hash.h"
+#include "id-pool.h"
+
+struct id_node {
+    struct hmap_node node;
+    uint32_t id;
+};
+
+struct id_pool {
+    struct hmap map;
+    uint32_t base;         /* IDs in the range of [base, base + n_ids). */
+    uint32_t n_ids;        /* Total number of ids in the pool. */
+    uint32_t next_free_id; /* Possible next free id. */
+};
+
+static void id_pool_init(struct id_pool *pool,
+                         uint32_t base, uint32_t n_ids);
+static void id_pool_uninit(struct id_pool *pool);
+static struct id_node *id_pool_find(struct id_pool *pool, uint32_t id);
+
+struct id_pool *
+id_pool_create(uint32_t base, uint32_t n_ids)
+{
+    struct id_pool *pool;
+
+    pool = xmalloc(sizeof *pool);
+    id_pool_init(pool, base, n_ids);
+
+    return pool;
+}
+
+void
+id_pool_destroy(struct id_pool *pool)
+{
+    id_pool_uninit(pool);
+    free(pool);
+}
+
+static void
+id_pool_init(struct id_pool *pool, uint32_t base, uint32_t n_ids)
+{
+    pool->base = base;
+    pool->n_ids = n_ids;
+    pool->next_free_id = base;
+    hmap_init(&pool->map);
+}
+
+static void
+id_pool_uninit(struct id_pool *pool)
+{
+    struct id_node *rid, *next;
+
+    HMAP_FOR_EACH_SAFE(rid, next, node, &pool->map) {
+        hmap_remove(&pool->map, &rid->node);
+        free(rid);
+    }
+
+    hmap_destroy(&pool->map);
+}
+
+static struct id_node *
+id_pool_find(struct id_pool *pool, uint32_t id)
+{
+    size_t hash;
+    struct id_node *rid;
+
+    hash = hash_int(id, 0);
+    HMAP_FOR_EACH_WITH_HASH(rid, node, hash, &pool->map) {
+        if (id == rid->id) {
+            return rid;
+        }
+    }
+    return NULL;
+}
+
+void
+id_pool_add(struct id_pool *pool, uint32_t id)
+{
+    struct id_node *rid = xmalloc(sizeof *rid);
+    size_t hash;
+
+    rid->id = id;
+    hash = hash_int(id, 0);
+    hmap_insert(&pool->map, &rid->node, hash);
+}
+
+uint32_t
+id_pool_alloc_id(struct id_pool *pool)
+{
+    uint32_t id;
+
+    if (pool->n_ids == 0) {
+        return 0;
+    }
+
+    if (!(id_pool_find(pool, pool->next_free_id))) {
+        id = pool->next_free_id;
+        goto found_free_id;
+    }
+
+    for(id = pool->base; id < pool->base + pool->n_ids; id++) {
+        if (id_pool_find(pool, id)) {
+            goto found_free_id;
+        }
+    }
+
+    /* Not available. */
+    return 0;
+
+found_free_id:
+    id_pool_add(pool, id);
+
+    if (id < pool->base + pool->n_ids) {
+        pool->next_free_id = id + 1;
+    } else {
+        pool->next_free_id = pool->base;
+    }
+
+    return id;
+}
+
+void
+id_pool_free_id(struct id_pool *pool, uint32_t id)
+{
+    struct id_node *rid;
+    if (id > pool->base && (id <= pool->base + pool->n_ids)) {
+        rid = id_pool_find(pool, id);
+        if (rid) {
+            hmap_remove(&pool->map, &rid->node);
+        }
+    }
+}
diff --git a/lib/id-pool.h b/lib/id-pool.h
new file mode 100644
index 0000000..71784ba
--- /dev/null
+++ b/lib/id-pool.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2014 Nicira, Inc.
+ * Copyright (c) 2014 Netronome.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ID_POOL_H
+#define ID_POOL_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+struct id_pool;
+
+struct id_pool *id_pool_create(uint32_t base, uint32_t n_ids);
+void id_pool_destroy(struct id_pool *pool);
+uint32_t id_pool_alloc_id(struct id_pool *pool);
+void id_pool_free_id(struct id_pool *pool, uint32_t id);
+void id_pool_add(struct id_pool *pool, uint32_t id);
+
+/*
+ * ID pool.
+ * ========
+ *
+ * Pool of unique 32bit ids.
+ * =============
+ *
+ * APIs are not thread safe.
+ *
+ */
+#endif
diff --git a/ofproto/ofproto-dpif-rid.c b/ofproto/ofproto-dpif-rid.c
index 236de4d..55d5c2b 100644
--- a/ofproto/ofproto-dpif-rid.c
+++ b/ofproto/ofproto-dpif-rid.c
@@ -16,46 +16,25 @@
 
 #include <config.h>
 
-#include "hmap.h"
-#include "hash.h"
+#include "id-pool.h"
 #include "ovs-thread.h"
 #include "ofproto-dpif-rid.h"
 
-struct rid_node {
-    struct hmap_node node;
-    uint32_t recirc_id;
-};
-
-struct rid_pool {
-    struct hmap map;
-    uint32_t base;         /* IDs in the range of [base, base + n_ids). */
-    uint32_t n_ids;        /* Total number of ids in the pool. */
-    uint32_t next_free_id; /* Possible next free id. */
-};
-
 struct recirc_id_pool {
     struct ovs_mutex lock;
-    struct rid_pool rids;
+    struct id_pool *rids;
 };
 
 #define RECIRC_ID_BASE  300
 #define RECIRC_ID_N_IDS  1024
 
-static void rid_pool_init(struct rid_pool *rids,
-                         uint32_t base, uint32_t n_ids);
-static void rid_pool_uninit(struct rid_pool *pool);
-static uint32_t rid_pool_alloc_id(struct rid_pool *pool);
-static void rid_pool_free_id(struct rid_pool *rids, uint32_t rid);
-static struct rid_node *rid_pool_find(struct rid_pool *rids, uint32_t id);
-static void rid_pool_add(struct rid_pool *rids, uint32_t id);
-
 struct recirc_id_pool *
 recirc_id_pool_create(void)
 {
     struct recirc_id_pool *pool;
 
     pool = xmalloc(sizeof *pool);
-    rid_pool_init(&pool->rids, RECIRC_ID_BASE, RECIRC_ID_N_IDS);
+    pool->rids = id_pool_create(RECIRC_ID_BASE, RECIRC_ID_N_IDS);
     ovs_mutex_init(&pool->lock);
 
     return pool;
@@ -64,7 +43,7 @@ recirc_id_pool_create(void)
 void
 recirc_id_pool_destroy(struct recirc_id_pool *pool)
 {
-    rid_pool_uninit(&pool->rids);
+    id_pool_destroy(pool->rids);
     ovs_mutex_destroy(&pool->lock);
     free(pool);
 }
@@ -75,7 +54,7 @@ recirc_id_alloc(struct recirc_id_pool *pool)
     uint32_t id;
 
     ovs_mutex_lock(&pool->lock);
-    id = rid_pool_alloc_id(&pool->rids);
+    id = id_pool_alloc_id(pool->rids);
     ovs_mutex_unlock(&pool->lock);
 
     return id;
@@ -85,101 +64,6 @@ void
 recirc_id_free(struct recirc_id_pool *pool, uint32_t id)
 {
     ovs_mutex_lock(&pool->lock);
-    rid_pool_free_id(&pool->rids, id);
+    id_pool_free_id(pool->rids, id);
     ovs_mutex_unlock(&pool->lock);
 }
-
-static void
-rid_pool_init(struct rid_pool *rids, uint32_t base, uint32_t n_ids)
-{
-    rids->base = base;
-    rids->n_ids = n_ids;
-    rids->next_free_id = base;
-    hmap_init(&rids->map);
-}
-
-static void
-rid_pool_uninit(struct rid_pool *rids)
-{
-    struct rid_node *rid, *next;
-
-    HMAP_FOR_EACH_SAFE(rid, next, node, &rids->map) {
-        hmap_remove(&rids->map, &rid->node);
-        free(rid);
-    }
-
-    hmap_destroy(&rids->map);
-}
-
-static struct rid_node *
-rid_pool_find(struct rid_pool *rids, uint32_t id)
-{
-    size_t hash;
-    struct rid_node *rid;
-
-    hash = hash_int(id, 0);
-    HMAP_FOR_EACH_WITH_HASH(rid, node, hash, &rids->map) {
-        if (id == rid->recirc_id) {
-            return rid;
-        }
-    }
-    return NULL;
-}
-
-static void
-rid_pool_add(struct rid_pool *rids, uint32_t id)
-{
-    struct rid_node *rid = xmalloc(sizeof *rid);
-    size_t hash;
-
-    rid->recirc_id = id;
-    hash = hash_int(id, 0);
-    hmap_insert(&rids->map, &rid->node, hash);
-}
-
-static uint32_t
-rid_pool_alloc_id(struct rid_pool *rids)
-{
-    uint32_t id;
-
-    if (rids->n_ids == 0) {
-        return 0;
-    }
-
-    if (!(rid_pool_find(rids, rids->next_free_id))) {
-        id = rids->next_free_id;
-        goto found_free_id;
-    }
-
-    for(id = rids->base; id < rids->base + rids->n_ids; id++) {
-        if (!rid_pool_find(rids, id)) {
-            goto found_free_id;
-        }
-    }
-
-    /* Not available. */
-    return 0;
-
-found_free_id:
-    rid_pool_add(rids, id);
-
-    if (id < rids->base + rids->n_ids) {
-        rids->next_free_id = id + 1;
-    } else {
-        rids->next_free_id = rids->base;
-    }
-
-    return id;
-}
-
-static void
-rid_pool_free_id(struct rid_pool *rids, uint32_t id)
-{
-    struct rid_node *rid;
-    if (id > rids->base && (id <= rids->base + rids->n_ids)) {
-        rid = rid_pool_find(rids, id);
-        if (rid) {
-            hmap_remove(&rids->map, &rid->node);
-        }
-    }
-}
-- 
2.1.1




More information about the dev mailing list