blob: 7b46237c3f6a3a7c9760844b2a27177541921220 [file] [log] [blame]
/*
* 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);
}