2 * Copyright (c) 2014 Nicira, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include "ovs-thread.h"
22 #include "ofproto-dpif-rid.h"
29 struct hmap_node node;
34 struct rid_map ridmap;
35 uint32_t base; /* IDs in the range of [base, base + n_ids). */
36 uint32_t n_ids; /* Total number of ids in the pool. */
37 uint32_t next_free_id; /* Possible next free id. */
40 struct recirc_id_pool {
41 struct ovs_mutex lock;
45 #define RECIRC_ID_BASE 300
46 #define RECIRC_ID_N_IDS 1024
48 static void rid_pool_init(struct rid_pool *rids,
49 uint32_t base, uint32_t n_ids);
50 static void rid_pool_uninit(struct rid_pool *pool);
51 static uint32_t rid_pool_alloc_id(struct rid_pool *pool);
52 static void rid_pool_free_id(struct rid_pool *rids, uint32_t rid);
53 static struct rid_node *rid_pool_find(struct rid_pool *rids, uint32_t id);
54 static struct rid_node *rid_pool_add(struct rid_pool *rids, uint32_t id);
56 struct recirc_id_pool *
57 recirc_id_pool_create(void)
59 struct recirc_id_pool *pool;
61 pool = xmalloc(sizeof *pool);
62 rid_pool_init(&pool->rids, RECIRC_ID_BASE, RECIRC_ID_N_IDS);
63 ovs_mutex_init(&pool->lock);
69 recirc_id_pool_destroy(struct recirc_id_pool *pool)
71 rid_pool_uninit(&pool->rids);
72 ovs_mutex_destroy(&pool->lock);
76 recirc_id_alloc(struct recirc_id_pool *pool)
80 ovs_mutex_lock(&pool->lock);
81 id = rid_pool_alloc_id(&pool->rids);
82 ovs_mutex_unlock(&pool->lock);
88 recirc_id_free(struct recirc_id_pool *pool, uint32_t id)
90 ovs_mutex_lock(&pool->lock);
91 rid_pool_free_id(&pool->rids, id);
92 ovs_mutex_unlock(&pool->lock);
96 rid_pool_init(struct rid_pool *rids, uint32_t base, uint32_t n_ids)
100 rids->next_free_id = base;
101 hmap_init(&rids->ridmap.map);
105 rid_pool_uninit(struct rid_pool *rids)
107 struct rid_node *rid, *next;
109 HMAP_FOR_EACH_SAFE(rid, next, node, &rids->ridmap.map) {
110 hmap_remove(&rids->ridmap.map, &rid->node);
114 hmap_destroy(&rids->ridmap.map);
117 static struct rid_node *
118 rid_pool_find(struct rid_pool *rids, uint32_t id)
121 struct rid_node *rid;
123 hash = hash_int(id, 0);
124 HMAP_FOR_EACH_WITH_HASH(rid, node, hash, &rids->ridmap.map) {
125 if (id == rid->recirc_id) {
132 static struct rid_node *
133 rid_pool_add(struct rid_pool *rids, uint32_t id)
135 struct rid_node *rid = xmalloc(sizeof *rid);
139 hash = hash_int(id, 0);
140 hmap_insert(&rids->ridmap.map, &rid->node, hash);
145 rid_pool_alloc_id(struct rid_pool *rids)
149 if (rids->n_ids == 0) {
153 if (!(rid_pool_find(rids, rids->next_free_id))) {
154 id = rids->next_free_id;
158 for(id = rids->base; id < rids->base + rids->n_ids; id++) {
159 if (rid_pool_find(rids, id)) {
168 rid_pool_add(rids, id);
170 if (id < rids->base + rids->n_ids) {
171 rids->next_free_id = id + 1;
173 rids->next_free_id = rids->base;
180 rid_pool_free_id(struct rid_pool *rids, uint32_t id)
182 struct rid_node *rid;
183 if (id > rids->base && (id <= rids->base + rids->n_ids)) {
184 rid = rid_pool_find(rids, id);
186 hmap_remove(&rids->ridmap.map, &rid->node);