diff --git a/tests/kernel/mem_pool/test_mpool_options/Makefile b/tests/kernel/mem_pool/test_mpool_options/Makefile new file mode 100644 index 00000000000..ffa0c5f4c13 --- /dev/null +++ b/tests/kernel/mem_pool/test_mpool_options/Makefile @@ -0,0 +1,4 @@ +BOARD ?= qemu_x86 +CONF_FILE ?= prj_split_defrag.conf + +include ${ZEPHYR_BASE}/Makefile.test diff --git a/tests/kernel/mem_pool/test_mpool_options/prj_defrag_split.conf b/tests/kernel/mem_pool/test_mpool_options/prj_defrag_split.conf new file mode 100644 index 00000000000..b2ba83e5926 --- /dev/null +++ b/tests/kernel/mem_pool/test_mpool_options/prj_defrag_split.conf @@ -0,0 +1,2 @@ +CONFIG_ZTEST=y +CONFIG_MEM_POOL_DEFRAG_BEFORE_SPLIT=y diff --git a/tests/kernel/mem_pool/test_mpool_options/prj_split_defrag.conf b/tests/kernel/mem_pool/test_mpool_options/prj_split_defrag.conf new file mode 100644 index 00000000000..f062d82737c --- /dev/null +++ b/tests/kernel/mem_pool/test_mpool_options/prj_split_defrag.conf @@ -0,0 +1,2 @@ +CONFIG_ZTEST=y +CONFIG_MEM_POOL_SPLIT_BEFORE_DEFRAG=y diff --git a/tests/kernel/mem_pool/test_mpool_options/prj_split_only.conf b/tests/kernel/mem_pool/test_mpool_options/prj_split_only.conf new file mode 100644 index 00000000000..db5e2c2d873 --- /dev/null +++ b/tests/kernel/mem_pool/test_mpool_options/prj_split_only.conf @@ -0,0 +1,2 @@ +CONFIG_ZTEST=y +CONFIG_MEM_POOL_SPLIT_ONLY=y diff --git a/tests/kernel/mem_pool/test_mpool_options/src/Makefile b/tests/kernel/mem_pool/test_mpool_options/src/Makefile new file mode 100644 index 00000000000..c31324db6a9 --- /dev/null +++ b/tests/kernel/mem_pool/test_mpool_options/src/Makefile @@ -0,0 +1,3 @@ +include $(ZEPHYR_BASE)/tests/Makefile.test + +obj-y = main.o test_mpool_options.o diff --git a/tests/kernel/mem_pool/test_mpool_options/src/main.c b/tests/kernel/mem_pool/test_mpool_options/src/main.c new file mode 100644 index 00000000000..675595a1808 --- /dev/null +++ b/tests/kernel/mem_pool/test_mpool_options/src/main.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * 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 + +extern void test_mpool_alloc_options(void); + +/*test case main entry*/ +void test_main(void *p1, void *p2, void *p3) +{ + ztest_test_suite(test_mpool_options, + ztest_unit_test(test_mpool_alloc_options)); + ztest_run_test_suite(test_mpool_options); +} diff --git a/tests/kernel/mem_pool/test_mpool_options/src/test_mpool_options.c b/tests/kernel/mem_pool/test_mpool_options/src/test_mpool_options.c new file mode 100644 index 00000000000..37fde817fe9 --- /dev/null +++ b/tests/kernel/mem_pool/test_mpool_options/src/test_mpool_options.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * 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. + */ + +/** + * @addtogroup t_mpool + * @{ + * @defgroup t_mpool_options test_mpool_options + * @brief TestPurpose: verify memory pool configure options + * @details All TESTPOINTs extracted from kernel documentation + * - Configure options covered + * - CONFIG_MEM_POOL_SPLIT_BEFORE_DEFRAG + * - CONFIG_MEM_POOL_DEFRAG_BEFORE_SPLIT + * - CONFIG_MEM_POOL_SPLIT_ONLY + * @} + */ + +#include +#define TIMEOUT 2000 +#define BLK_SIZE_MIN 4 +#define BLK_SIZE_MID 16 +#define BLK_SIZE_MAX 64 +#define BLK_NUM_MIN 32 +#define BLK_NUM_MAX 2 +#define BLK_ALIGN BLK_SIZE_MIN + +K_MEM_POOL_DEFINE(mpool1, BLK_SIZE_MIN, BLK_SIZE_MAX, BLK_NUM_MAX, BLK_ALIGN); + +static struct k_mem_block block[BLK_NUM_MIN]; +static size_t block_size[] = { + BLK_SIZE_MIN, BLK_SIZE_MIN, BLK_SIZE_MIN, BLK_SIZE_MIN, + BLK_SIZE_MID, BLK_SIZE_MID, BLK_SIZE_MID}; +static int block_count = sizeof(block_size)/sizeof(size_t); + +#ifdef CONFIG_MEM_POOL_SPLIT_BEFORE_DEFRAG +static void tmpool_split_before_defrag(void) +{ + struct k_mem_block block_split, block_max; + /** + * TESTPOINT: This option instructs a memory pool to try splitting a + * larger unused block if an unused block of the required size is not + * available; only if no such blocks exist will the memory pool try + * merging smaller unused blocks. + * Test steps: mpool1 initial status (F for free, U for used) + * 4F 4F 4F 4F 16U 16U 16U 64F + * 1. request a mid-size (16) block + * 2. verify the previous block was splited from 64F, since + * consequently a further request to max-size block fail + */ + TC_PRINT("CONFIG_MEM_POOL_SPLIT_BEFORE_DEFRAG\n"); + /* 1. request a mid-size block*/ + assert_true(k_mem_pool_alloc(&mpool1, &block_split, BLK_SIZE_MID, + K_NO_WAIT) == 0, NULL); + /* 2. verify the previous block was split from the 2nd max block*/ + assert_true(k_mem_pool_alloc(&mpool1, &block_max, BLK_SIZE_MAX, + TIMEOUT) == -EAGAIN, NULL); + k_mem_pool_free(&block_split); +} +#endif + +#ifdef CONFIG_MEM_POOL_DEFRAG_BEFORE_SPLIT +static void tmpool_defrag_before_split(void) +{ + struct k_mem_block block_defrag, block_max; + /** + * TESTPOINT: This option instructs a memory pool to try merging smaller + * unused blocks if an unused block of the required size is not + * available; only if this does not generate a sufficiently large block + * will the memory pool try splitting a larger unused block. + * Test steps: mpool1 initial status (F for free, U for used) + * 4F 4F 4F 4F 16U 16U 16U 64F + * 1. request a mid-size (16) block + * 2. verify the previous block was defrag from 4*4F, since + * consequently a further request to max-size block pass + */ + TC_PRINT("CONFIG_MEM_POOL_DEFRAG_BEFORE_SPLIT\n"); + /* 1. request a mid-size block*/ + assert_true(k_mem_pool_alloc(&mpool1, &block_defrag, BLK_SIZE_MID, + TIMEOUT) == 0, NULL); + /* 2. verify the previous block was defrag from block[0~3]*/ + assert_true(k_mem_pool_alloc(&mpool1, &block_max, BLK_SIZE_MAX, + K_NO_WAIT) == 0, NULL); + k_mem_pool_free(&block_defrag); + k_mem_pool_free(&block_max); +} +#endif + +#ifdef CONFIG_MEM_POOL_SPLIT_ONLY +static void tmpool_split_only(void) +{ + struct k_mem_block block_mid[4], block_fail; + /** + * TESTPOINT: This option instructs a memory pool to try splitting a + * larger unused block if an unused block of the required size is not + * available; if no such blocks exist the block allocation operation + * fails. + * Test steps: mpool1 initial status (F for free, U for used) + * 4F 4F 4F 4F 16U 16U 16U 64F + * 1. request 4 mid-size (16) blocks, verify allocation + * ok via splitting the 64F max block + * 2. request another mid-size (16) block, verify allocation + * failed since no large blocks to split, nor the memory + * pool is configured to do defrag (merging) + */ + TC_PRINT("CONFIG_MEM_POOL_SPLIT_ONLY\n"); + for (int i = 0; i < 4; i++) { + /* 1. verify allocation ok via spliting the max block*/ + assert_true(k_mem_pool_alloc(&mpool1, &block_mid[i], + BLK_SIZE_MID, K_NO_WAIT) == 0, NULL); + } + /* 2. verify allocation failed since no large blocks nor defrag*/ + assert_true(k_mem_pool_alloc(&mpool1, &block_fail, BLK_SIZE_MID, + TIMEOUT) == -EAGAIN, NULL); + for (int i = 0; i < 4; i++) { + k_mem_pool_free(&block_mid[i]); + } +} +#endif + +/* test cases*/ +void test_mpool_alloc_options(void) +{ + /* allocate 7 blocks, in size 4 4 4 4 16 16 16, respectively*/ + for (int i = 0; i < block_count; i++) { + assert_true(k_mem_pool_alloc(&mpool1, &block[i], block_size[i], + K_NO_WAIT) == 0, NULL); + } + /* free block [0~3]*/ + for (int i = 0; i < 4; i++) { + k_mem_pool_free(&block[i]); + } + + #ifdef CONFIG_MEM_POOL_SPLIT_BEFORE_DEFRAG + tmpool_split_before_defrag(); + #endif + #ifdef CONFIG_MEM_POOL_DEFRAG_BEFORE_SPLIT + tmpool_defrag_before_split(); + #endif + #ifdef CONFIG_MEM_POOL_SPLIT_ONLY + tmpool_split_only(); + #endif + + /* test case tear down*/ + for (int i = 4; i < block_count; i++) { + k_mem_pool_free(&block[i]); + } +} + diff --git a/tests/kernel/mem_pool/test_mpool_options/testcase.ini b/tests/kernel/mem_pool/test_mpool_options/testcase.ini new file mode 100644 index 00000000000..a16f4aa313a --- /dev/null +++ b/tests/kernel/mem_pool/test_mpool_options/testcase.ini @@ -0,0 +1,11 @@ +[test_mpool_split_defrag] +tags = kernel +extra_args = CONF_FILE=prj_split_defrag.conf + +[test_mpool_defrag_split] +tags = kernel +extra_args = CONF_FILE=prj_defrag_split.conf + +[test_mpool_split_only] +tags = kernel +extra_args = CONF_FILE=prj_split_only.conf