| /* |
| * Copyright (c) 2016 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #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]; |
| |
| (void)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.*/ |
| zassert_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. |
| */ |
| zassert_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++) { |
| zassert_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 |
| */ |
| zassert_true((u32_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; |
| s64_t tms; |
| |
| for (int i = 0; i < BLK_NUM; i++) { |
| zassert_true(k_mem_slab_alloc(pslab, &block[i], K_NO_WAIT) == 0, |
| NULL); |
| } |
| |
| /** TESTPOINT: Use K_NO_WAIT to return without waiting*/ |
| /** TESTPOINT: -ENOMEM Returned without waiting.*/ |
| zassert_equal(k_mem_slab_alloc(pslab, &block_fail, K_NO_WAIT), -ENOMEM, |
| NULL); |
| /** TESTPOINT: -EAGAIN Waiting period timed out*/ |
| tms = k_uptime_get(); |
| zassert_equal(k_mem_slab_alloc(pslab, &block_fail, TIMEOUT), -EAGAIN, |
| NULL); |
| /** |
| * TESTPOINT: timeout Maximum time to wait for operation to |
| * complete (in milliseconds) |
| */ |
| zassert_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++) { |
| zassert_true(k_mem_slab_alloc(pslab, &block[i], K_NO_WAIT) == 0, |
| NULL); |
| /** TESTPOINT: Get the number of used blocks in a memory slab.*/ |
| zassert_equal(k_mem_slab_num_used_get(pslab), i + 1, NULL); |
| /** |
| * TESTPOINT: Get the number of unused blocks in a memory slab. |
| */ |
| zassert_equal(k_mem_slab_num_free_get(pslab), BLK_NUM - 1 - i, NULL); |
| } |
| |
| zassert_equal(k_mem_slab_alloc(pslab, &block_fail, K_NO_WAIT), -ENOMEM, |
| NULL); |
| /* free get on allocation failure*/ |
| zassert_equal(k_mem_slab_num_free_get(pslab), 0, NULL); |
| /* used get on allocation failure*/ |
| zassert_equal(k_mem_slab_num_used_get(pslab), BLK_NUM, NULL); |
| |
| zassert_equal(k_mem_slab_alloc(pslab, &block_fail, TIMEOUT), -EAGAIN, |
| NULL); |
| zassert_equal(k_mem_slab_num_free_get(pslab), 0, NULL); |
| zassert_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]); |
| zassert_equal(k_mem_slab_num_free_get(pslab), i + 1, NULL); |
| zassert_equal(k_mem_slab_num_used_get(pslab), BLK_NUM - 1 - i, NULL); |
| } |
| } |
| |
| /*test cases*/ |
| /** |
| * @brief Initialize the memory slab using k_mem_slab_init() |
| * and allocates/frees blocks. |
| * |
| * @details Initialize 3 memory blocks of block size 8 bytes |
| * using @see k_mem_slab_init() and check if number of used blocks |
| * is 0 and free blocks is equal to number of blocks initialized. |
| * |
| * @ingroup kernel_memory_slab_tests |
| */ |
| void test_mslab_kinit(void) |
| { |
| k_mem_slab_init(&mslab, tslab, BLK_SIZE, BLK_NUM); |
| zassert_equal(k_mem_slab_num_used_get(&mslab), 0, NULL); |
| zassert_equal(k_mem_slab_num_free_get(&mslab), BLK_NUM, NULL); |
| } |
| |
| /** |
| * @brief Verify K_MEM_SLAB_DEFINE() with allocates/frees blocks. |
| * |
| * @details Initialize 3 memory blocks of block size 8 bytes |
| * using @see K_MEM_SLAB_DEFINE() and check if number of used blocks |
| * is 0 and free blocks is equal to number of blocks initialized. |
| * |
| * @ingroup kernel_memory_slab_tests |
| */ |
| void test_mslab_kdefine(void) |
| { |
| zassert_equal(k_mem_slab_num_used_get(&kmslab), 0, NULL); |
| zassert_equal(k_mem_slab_num_free_get(&kmslab), BLK_NUM, NULL); |
| } |
| |
| /** |
| * @brief Verify alloc and free of blocks from mem_slab |
| * |
| * @ingroup kernel_memory_slab_tests |
| */ |
| void test_mslab_alloc_free_thread(void) |
| { |
| |
| tmslab_alloc_free(&mslab); |
| } |
| |
| /** |
| * @brief Allocate memory blocks and check for alignment of 8 bytes |
| * |
| * @details Allocate 3 blocks of memory from 2 memory slabs |
| * respectively and check if all blocks are aligned to 8 bytes |
| * and free them. |
| * |
| * @ingroup kernel_memory_slab_tests |
| */ |
| void test_mslab_alloc_align(void) |
| { |
| tmslab_alloc_align(&mslab); |
| tmslab_alloc_align(&kmslab); |
| } |
| |
| /** |
| * @brief Verify allocation of memory blocks with timeouts |
| * |
| * @details Allocate 3 memory blocks from memory slab. Check |
| * allocation of another memory block with NO_WAIT set, since |
| * there are no blocks left to allocate in the memory slab, |
| * the allocation fails with return value -ENOMEM. Then the |
| * system up time is obtained, memory block allocation is |
| * tried with timeout of 2000 ms. Now the allocation API |
| * returns -EAGAIN as the waiting period is timeout. The |
| * test case also checks if timeout has really happened by |
| * checking delta period between the allocation request |
| * was made and return of -EAGAIN. |
| * |
| * @ingroup kernel_memory_slab_tests |
| */ |
| void test_mslab_alloc_timeout(void) |
| { |
| tmslab_alloc_timeout(&mslab); |
| } |
| |
| /** |
| * @brief Verify count of allocated blocks |
| * |
| * @details The test case allocates 3 blocks one after the |
| * other by checking for used block and free blocks in the |
| * memory slab - mslab. Once all 3 blocks are allocated, |
| * one more block is tried to allocates, which fails with |
| * return value -ENOMEM. It also checks the allocation with |
| * timeout. Again checks for used block and free blocks |
| * number using @see k_mem_slab_num_used_get() and |
| * @see k_mem_slab_num_free_get(). |
| * |
| * @ingroup kernel_memory_slab_tests |
| */ |
| void test_mslab_used_get(void) |
| { |
| tmslab_used_get(&mslab); |
| tmslab_used_get(&kmslab); |
| } |