diff options
-rw-r--r-- | src/plugins/unittest/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/plugins/unittest/pool_test.c | 62 | ||||
-rw-r--r-- | src/vppinfra/pool.h | 65 | ||||
-rw-r--r-- | test/test_vlib.py | 13 |
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) |