summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/unittest/CMakeLists.txt1
-rw-r--r--src/plugins/unittest/pool_test.c62
-rw-r--r--src/vppinfra/pool.h65
-rw-r--r--test/test_vlib.py13
4 files changed, 112 insertions, 29 deletions
diff --git a/src/plugins/unittest/CMakeLists.txt b/src/plugins/unittest/CMakeLists.txt
index 6276a92d749..115ced3393b 100644
--- a/src/plugins/unittest/CMakeLists.txt
+++ b/src/plugins/unittest/CMakeLists.txt
@@ -40,6 +40,7 @@ add_vpp_plugin(unittest
mfib_test.c
mpcap_node.c
policer_test.c
+ pool_test.c
punt_test.c
rbtree_test.c
session_test.c
diff --git a/src/plugins/unittest/pool_test.c b/src/plugins/unittest/pool_test.c
new file mode 100644
index 00000000000..237b6beea09
--- /dev/null
+++ b/src/plugins/unittest/pool_test.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2021 Dave Barach
+ * 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 <vlib/vlib.h>
+
+static clib_error_t *
+test_pool_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ int i;
+ u64 *pool;
+
+ pool_init_fixed (pool, 2048);
+
+ i = 0;
+
+ while (pool_free_elts (pool) > 0)
+ {
+ u64 *p __attribute__ ((unused));
+
+ pool_get (pool, p);
+ i++;
+ }
+
+ vlib_cli_output (vm, "allocated %d elts\n", i);
+
+ for (--i; i >= 0; i--)
+ {
+ pool_put_index (pool, i);
+ }
+
+ ALWAYS_ASSERT (pool_free_elts (pool) == 2048);
+
+ vlib_cli_output (vm, "Test succeeded...\n");
+ return 0;
+}
+
+VLIB_CLI_COMMAND (test_pool_command, static) = {
+ .path = "test pool",
+ .short_help = "vppinfra pool.h tests",
+ .function = test_pool_command_fn,
+};
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/vppinfra/pool.h b/src/vppinfra/pool.h
index 116c1cd1321..4a0414253b4 100644
--- a/src/vppinfra/pool.h
+++ b/src/vppinfra/pool.h
@@ -173,8 +173,12 @@ pool_free_elts (void *v)
{
n_free += vec_len (p->free_indices);
- /* Space left at end of vector? */
- n_free += vec_capacity (v, sizeof (p[0])) - vec_len (v);
+ /*
+ * Space left at end of vector?
+ * Fixed-size pools have max_elts set non-zero,
+ */
+ if (p->max_elts == 0)
+ n_free += vec_capacity (v, sizeof (p[0])) - vec_len (v);
}
return n_free;
@@ -298,33 +302,36 @@ do { \
#define pool_is_free_index(P,I) pool_is_free((P),(P)+(I))
/** Free an object E in pool P. */
-#define pool_put(P,E) \
-do { \
- typeof (P) _pool_var(p__) = (P); \
- typeof (E) _pool_var(e__) = (E); \
- pool_header_t * _pool_var (p) = pool_header (_pool_var(p__)); \
- uword _pool_var (l) = _pool_var(e__) - _pool_var(p__); \
- ASSERT (vec_is_member (_pool_var(p__), _pool_var(e__))); \
- ASSERT (! pool_is_free (_pool_var(p__), _pool_var(e__))); \
- \
- /* Add element to free bitmap and to free list. */ \
- _pool_var (p)->free_bitmap = \
- clib_bitmap_ori_notrim (_pool_var (p)->free_bitmap, \
- _pool_var (l)); \
- \
- /* Preallocated pool? */ \
- if (_pool_var (p)->max_elts) \
- { \
- ASSERT(_pool_var(l) < _pool_var (p)->max_elts); \
- _pool_var(p)->free_indices[_vec_len(_pool_var(p)->free_indices)] = \
- _pool_var(l); \
- _vec_len(_pool_var(p)->free_indices) += 1; \
- } \
- else \
- vec_add1 (_pool_var (p)->free_indices, _pool_var (l)); \
- \
- CLIB_MEM_POISON(_pool_var(e__), sizeof(_pool_var(e__)[0])); \
-} while (0)
+#define pool_put(P, E) \
+ do \
+ { \
+ typeof (P) _pool_var (p__) = (P); \
+ typeof (E) _pool_var (e__) = (E); \
+ pool_header_t *_pool_var (p) = pool_header (_pool_var (p__)); \
+ uword _pool_var (l) = _pool_var (e__) - _pool_var (p__); \
+ if (_pool_var (p)->max_elts == 0) \
+ ASSERT (vec_is_member (_pool_var (p__), _pool_var (e__))); \
+ ASSERT (!pool_is_free (_pool_var (p__), _pool_var (e__))); \
+ \
+ /* Add element to free bitmap and to free list. */ \
+ _pool_var (p)->free_bitmap = \
+ clib_bitmap_ori_notrim (_pool_var (p)->free_bitmap, _pool_var (l)); \
+ \
+ /* Preallocated pool? */ \
+ if (_pool_var (p)->max_elts) \
+ { \
+ ASSERT (_pool_var (l) < _pool_var (p)->max_elts); \
+ _pool_var (p) \
+ ->free_indices[_vec_len (_pool_var (p)->free_indices)] = \
+ _pool_var (l); \
+ _vec_len (_pool_var (p)->free_indices) += 1; \
+ } \
+ else \
+ vec_add1 (_pool_var (p)->free_indices, _pool_var (l)); \
+ \
+ CLIB_MEM_POISON (_pool_var (e__), sizeof (_pool_var (e__)[0])); \
+ } \
+ while (0)
/** Free pool element with given index. */
#define pool_put_index(p,i) \
diff --git a/test/test_vlib.py b/test/test_vlib.py
index a9a5f6aeb89..31fb72990f0 100644
--- a/test/test_vlib.py
+++ b/test/test_vlib.py
@@ -204,6 +204,19 @@ class TestVlib(VppTestCase):
time.sleep(70)
self.logger.info("Reaper should be complete...")
+ def test_pool(self):
+ """ Fixed-size Pool Test """
+
+ cmds = ["test pool",
+ ]
+
+ for cmd in cmds:
+ r = self.vapi.cli_return_response(cmd)
+ if r.retval != 0:
+ if hasattr(r, 'reply'):
+ self.logger.info(cmd + " FAIL reply " + r.reply)
+ else:
+ self.logger.info(cmd + " FAIL retval " + str(r.retval))
if __name__ == '__main__':
unittest.main(testRunner=VppTestRunner)