| /* |
| * Copyright (c) 2016 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| /** |
| * @addtogroup t_mslab |
| * @{ |
| * @defgroup t_mslab_api test_mslab_api |
| * @brief TestPurpose: verify memory slab APIs. |
| * @details All TESTPOINTs extracted from kernel-doc comments in <kernel.h> |
| * - API coverage |
| * - K_MEM_SLAB_DEFINE |
| * - k_mem_slab_init |
| * - k_mem_slab_alloc |
| * - k_mem_slab_free |
| * - k_mem_slab_num_used_get |
| * - k_mem_slab_num_free_get |
| * @} |
| */ |
| |
| #include <ztest.h> |
| #include "test_mslab.h" |
| |
| /** TESTPOINT: Statically define and initialize a memory slab*/ |
| K_MEM_SLAB_DEFINE(kmslab, BLK_SIZE, BLK_NUM, BLK_ALIGN); |
| static char __aligned(BLK_ALIGN) tslab[BLK_SIZE * BLK_NUM]; |
| static struct k_mem_slab mslab; |
| |
| void tmslab_alloc_free(void *data) |
| { |
| struct k_mem_slab *pslab = (struct k_mem_slab *)data; |
| void *block[BLK_NUM]; |
| |
| memset(block, 0, sizeof(block)); |
| /** |
| * TESTPOINT: The memory slab's buffer contains @a slab_num_blocks |
| * memory blocks that are @a slab_block_size bytes long. |
| */ |
| for (int i = 0; i < BLK_NUM; i++) { |
| /** TESTPOINT: Allocate memory from a memory slab.*/ |
| /** TESTPOINT: @retval 0 Memory allocated.*/ |
| assert_true(k_mem_slab_alloc(pslab, &block[i], K_NO_WAIT) == 0, |
| NULL); |
| /** |
| * TESTPOINT: The block address area pointed at by @a mem is set |
| * to the starting address of the memory block. |
| */ |
| assert_not_null(block[i], NULL); |
| } |
| for (int i = 0; i < BLK_NUM; i++) { |
| /** TESTPOINT: Free memory allocated from a memory slab.*/ |
| k_mem_slab_free(pslab, &block[i]); |
| } |
| } |
| |
| static void tmslab_alloc_align(void *data) |
| { |
| struct k_mem_slab *pslab = (struct k_mem_slab *)data; |
| void *block[BLK_NUM]; |
| |
| for (int i = 0; i < BLK_NUM; i++) { |
| assert_true(k_mem_slab_alloc(pslab, &block[i], K_NO_WAIT) == 0, |
| NULL); |
| /** |
| * TESTPOINT: To ensure that each memory block is similarly |
| * aligned to this boundary |
| */ |
| assert_true((uint32_t)block[i] % BLK_ALIGN == 0, NULL); |
| } |
| for (int i = 0; i < BLK_NUM; i++) { |
| k_mem_slab_free(pslab, &block[i]); |
| } |
| } |
| |
| static void tmslab_alloc_timeout(void *data) |
| { |
| struct k_mem_slab *pslab = (struct k_mem_slab *)data; |
| void *block[BLK_NUM], *block_fail; |
| int64_t tms; |
| |
| for (int i = 0; i < BLK_NUM; i++) { |
| assert_true(k_mem_slab_alloc(pslab, &block[i], K_NO_WAIT) == 0, |
| NULL); |
| } |
| |
| /** TESTPOINT: Use K_NO_WAIT to return without waiting*/ |
| /** TESTPOINT: @retval -ENOMEM Returned without waiting.*/ |
| assert_equal(k_mem_slab_alloc(pslab, &block_fail, K_NO_WAIT), -ENOMEM, |
| NULL); |
| /** TESTPOINT: @retval -EAGAIN Waiting period timed out*/ |
| tms = k_uptime_get(); |
| assert_equal(k_mem_slab_alloc(pslab, &block_fail, TIMEOUT), -EAGAIN, |
| NULL); |
| /** |
| * TESTPOINT: @param timeout Maximum time to wait for operation to |
| * complete (in milliseconds) |
| */ |
| assert_true(k_uptime_delta(&tms) >= TIMEOUT, NULL); |
| |
| for (int i = 0; i < BLK_NUM; i++) { |
| k_mem_slab_free(pslab, &block[i]); |
| } |
| } |
| |
| static void tmslab_used_get(void *data) |
| { |
| struct k_mem_slab *pslab = (struct k_mem_slab *)data; |
| void *block[BLK_NUM], *block_fail; |
| |
| for (int i = 0; i < BLK_NUM; i++) { |
| assert_true(k_mem_slab_alloc(pslab, &block[i], K_NO_WAIT) == 0, |
| NULL); |
| /** TESTPOINT: Get the number of used blocks in a memory slab.*/ |
| assert_equal(k_mem_slab_num_used_get(pslab), i+1, NULL); |
| /** |
| * TESTPOINT: Get the number of unused blocks in a memory slab. |
| */ |
| assert_equal(k_mem_slab_num_free_get(pslab), BLK_NUM-1-i, NULL); |
| } |
| |
| assert_equal(k_mem_slab_alloc(pslab, &block_fail, K_NO_WAIT), -ENOMEM, |
| NULL); |
| /* free get on allocation failure*/ |
| assert_equal(k_mem_slab_num_free_get(pslab), 0, NULL); |
| /* used get on allocation failure*/ |
| assert_equal(k_mem_slab_num_used_get(pslab), BLK_NUM, NULL); |
| |
| assert_equal(k_mem_slab_alloc(pslab, &block_fail, TIMEOUT), -EAGAIN, |
| NULL); |
| assert_equal(k_mem_slab_num_free_get(pslab), 0, NULL); |
| assert_equal(k_mem_slab_num_used_get(pslab), BLK_NUM, NULL); |
| |
| for (int i = 0; i < BLK_NUM; i++) { |
| k_mem_slab_free(pslab, &block[i]); |
| assert_equal(k_mem_slab_num_free_get(pslab), i+1, NULL); |
| assert_equal(k_mem_slab_num_used_get(pslab), BLK_NUM-1-i, NULL); |
| } |
| } |
| |
| /*test cases*/ |
| void test_mslab_kinit(void) |
| { |
| k_mem_slab_init(&mslab, tslab, BLK_SIZE, BLK_NUM); |
| assert_equal(k_mem_slab_num_used_get(&mslab), 0, NULL); |
| assert_equal(k_mem_slab_num_free_get(&mslab), BLK_NUM, NULL); |
| } |
| |
| void test_mslab_kdefine(void) |
| { |
| assert_equal(k_mem_slab_num_used_get(&kmslab), 0, NULL); |
| assert_equal(k_mem_slab_num_free_get(&kmslab), BLK_NUM, NULL); |
| } |
| |
| void test_mslab_alloc_free_thread(void) |
| { |
| |
| tmslab_alloc_free(&mslab); |
| } |
| |
| void test_mslab_alloc_align(void) |
| { |
| tmslab_alloc_align(&mslab); |
| tmslab_alloc_align(&kmslab); |
| } |
| |
| void test_mslab_alloc_timeout(void) |
| { |
| tmslab_alloc_timeout(&mslab); |
| } |
| |
| void test_mslab_used_get(void) |
| { |
| tmslab_used_get(&mslab); |
| tmslab_used_get(&kmslab); |
| } |