tests: kernel: added memory pool concept test
TestPurpose: verify memory pool concepts. All TESTPOINTs extracted from kernel documentation. https://www.zephyrproject.org/doc/kernel/memory/pools.html#concepts ZEP-1210 Change-Id: I6250e4c26ddf361e74a76c23082cfdb376705560 Signed-off-by: Sharron LIU <sharron.liu@intel.com>
This commit is contained in:
parent
415e71e04c
commit
61c53373ee
10 changed files with 364 additions and 0 deletions
4
tests/kernel/mem_pool/test_mpool_concept/Makefile
Normal file
4
tests/kernel/mem_pool/test_mpool_concept/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
|||
BOARD ?= qemu_x86
|
||||
CONF_FILE = prj.conf
|
||||
|
||||
include ${ZEPHYR_BASE}/Makefile.test
|
1
tests/kernel/mem_pool/test_mpool_concept/prj.conf
Normal file
1
tests/kernel/mem_pool/test_mpool_concept/prj.conf
Normal file
|
@ -0,0 +1 @@
|
|||
CONFIG_ZTEST=y
|
5
tests/kernel/mem_pool/test_mpool_concept/src/Makefile
Normal file
5
tests/kernel/mem_pool/test_mpool_concept/src/Makefile
Normal file
|
@ -0,0 +1,5 @@
|
|||
include $(ZEPHYR_BASE)/tests/Makefile.test
|
||||
|
||||
obj-y = main.o test_mpool_alloc_wait.o test_mpool_alloc_size.o
|
||||
obj-y += test_mpool_merge_fail_diff_parent.o
|
||||
obj-y += test_mpool_merge_fail_diff_size.o
|
33
tests/kernel/mem_pool/test_mpool_concept/src/main.c
Normal file
33
tests/kernel/mem_pool/test_mpool_concept/src/main.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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 <ztest.h>
|
||||
extern void test_mpool_alloc_wait_prio(void);
|
||||
extern void test_mpool_alloc_size_roundup(void);
|
||||
extern void test_mpool_alloc_merge_failed_diff_size(void);
|
||||
extern void test_mpool_alloc_merge_failed_diff_parent(void);
|
||||
|
||||
/*test case main entry*/
|
||||
void test_main(void *p1, void *p2, void *p3)
|
||||
{
|
||||
ztest_test_suite(test_mpool_concept,
|
||||
ztest_unit_test(test_mpool_alloc_wait_prio),
|
||||
ztest_unit_test(test_mpool_alloc_size_roundup),
|
||||
ztest_unit_test(test_mpool_alloc_merge_failed_diff_size),
|
||||
ztest_unit_test(test_mpool_alloc_merge_failed_diff_parent));
|
||||
ztest_run_test_suite(test_mpool_concept);
|
||||
}
|
||||
|
23
tests/kernel/mem_pool/test_mpool_concept/src/test_mpool.h
Normal file
23
tests/kernel/mem_pool/test_mpool_concept/src/test_mpool.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define TIMEOUT 2000
|
||||
#define STACK_SIZE 512
|
||||
#define BLK_SIZE_MIN 4
|
||||
#define BLK_SIZE_MAX 16
|
||||
#define BLK_NUM_MIN 8
|
||||
#define BLK_NUM_MAX 2
|
||||
#define BLK_ALIGN BLK_SIZE_MIN
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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 <ztest.h>
|
||||
#include "test_mpool.h"
|
||||
|
||||
#define TEST_SIZE ((BLK_SIZE_MAX>>2)+1)
|
||||
|
||||
extern struct k_mem_pool mpool1;
|
||||
|
||||
/*test cases*/
|
||||
void test_mpool_alloc_size_roundup(void)
|
||||
{
|
||||
struct k_mem_block block[BLK_NUM_MAX], block_fail;
|
||||
|
||||
/**
|
||||
* TESTPOINT: When an application issues a request for a memory block,
|
||||
* the memory pool first determines the size of the smallest block that
|
||||
* will satisfy the request
|
||||
*/
|
||||
for (int i = 0; i < BLK_NUM_MAX; i++) {
|
||||
/*request a size for the mpool to round up to "BLK_SIZE_MAX"*/
|
||||
assert_true(k_mem_pool_alloc(&mpool1, &block[i], TEST_SIZE,
|
||||
K_NO_WAIT) == 0, NULL);
|
||||
}
|
||||
/*verify consequently no more blocks available*/
|
||||
assert_true(k_mem_pool_alloc(&mpool1, &block_fail, BLK_SIZE_MIN,
|
||||
K_NO_WAIT) == -ENOMEM, NULL);
|
||||
|
||||
/*test case tear down*/
|
||||
for (int i = 0; i < BLK_NUM_MAX; i++) {
|
||||
k_mem_pool_free(&block[i]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* 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_concept test_mpool_concept
|
||||
* @brief TestPurpose: verify memory pool concepts.
|
||||
* @details All TESTPOINTs extracted from kernel documentation.
|
||||
* TESTPOINTs cover testable kernel behaviours that preserve across internal
|
||||
* implementation change or kernel version change.
|
||||
* As a black-box test, TESTPOINTs do not cover internal operations.
|
||||
*
|
||||
* TESTPOINTs duplicated to <kernel.h> are covered in API test:
|
||||
* - TESTPOINT: ensure that all memory blocks in the buffer are similarly
|
||||
* aligned to this boundary
|
||||
* - TESTPOINT: Following a successful allocation, the data field of the block
|
||||
* descriptor supplied by the thread indicates the starting address of the
|
||||
* memory block
|
||||
* - TESTPOINT: memory pool blocks can be recursively partitioned into quarters
|
||||
* until blocks of the minimum size are obtained
|
||||
* - TESTPOINT: if a suitable block can’t be created, the allocation request
|
||||
* fails
|
||||
*
|
||||
* TESTPOINTs related to kconfig are covered in kconfig test:
|
||||
* - TESTPOINT: If the block set does not contain a free block, the memory pool
|
||||
* attempts to create one automatically by splitting a free block of a larger
|
||||
* size or by merging free blocks of smaller sizes
|
||||
*
|
||||
* TESTPOINTS related to multiple instances are covered in re-entrance test:
|
||||
* - TESTPOINT: More than one memory pool can be defined, if needed. For
|
||||
* example, different applications can utilize different memory pools
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <ztest.h>
|
||||
#include "test_mpool.h"
|
||||
|
||||
#define THREAD_NUM 3
|
||||
K_MEM_POOL_DEFINE(mpool1, BLK_SIZE_MIN, BLK_SIZE_MAX, BLK_NUM_MAX, BLK_ALIGN);
|
||||
|
||||
static char __noinit __stack tstack[THREAD_NUM][STACK_SIZE];
|
||||
static struct k_sem sync_sema;
|
||||
static struct k_mem_block block_ok;
|
||||
|
||||
/*thread entry*/
|
||||
void tmpool_alloc_wait_timeout(void *p1, void *p2, void *p3)
|
||||
{
|
||||
struct k_mem_block block;
|
||||
|
||||
assert_true(k_mem_pool_alloc(&mpool1, &block, BLK_SIZE_MIN,
|
||||
TIMEOUT) == -EAGAIN, NULL);
|
||||
k_sem_give(&sync_sema);
|
||||
}
|
||||
|
||||
void tmpool_alloc_wait_ok(void *p1, void *p2, void *p3)
|
||||
{
|
||||
assert_true(k_mem_pool_alloc(&mpool1, &block_ok, BLK_SIZE_MIN,
|
||||
TIMEOUT) == 0, NULL);
|
||||
k_sem_give(&sync_sema);
|
||||
}
|
||||
|
||||
/*test cases*/
|
||||
void test_mpool_alloc_wait_prio(void)
|
||||
{
|
||||
struct k_mem_block block[BLK_NUM_MIN];
|
||||
k_tid_t tid[THREAD_NUM];
|
||||
|
||||
k_sem_init(&sync_sema, 0, THREAD_NUM);
|
||||
/*allocated up all blocks*/
|
||||
for (int i = 0; i < BLK_NUM_MIN; i++) {
|
||||
assert_true(k_mem_pool_alloc(&mpool1, &block[i], BLK_SIZE_MIN,
|
||||
K_NO_WAIT) == 0, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* TESTPOINT: when a suitable memory block becomes available, it is
|
||||
* given to the highest-priority thread that has waited the longest
|
||||
*/
|
||||
/**
|
||||
* TESTPOINT: If a block of the desired size is unavailable, a thread
|
||||
* can optionally wait for one to become available
|
||||
*/
|
||||
/*the low-priority thread*/
|
||||
tid[0] = k_thread_spawn(tstack[0], STACK_SIZE,
|
||||
tmpool_alloc_wait_timeout, NULL, NULL, NULL,
|
||||
K_PRIO_PREEMPT(1), 0, 0);
|
||||
/*the highest-priority thread that has waited the longest*/
|
||||
tid[1] = k_thread_spawn(tstack[1], STACK_SIZE,
|
||||
tmpool_alloc_wait_ok, NULL, NULL, NULL,
|
||||
K_PRIO_PREEMPT(0), 0, 10);
|
||||
/*the highest-priority thread that has waited shorter*/
|
||||
tid[2] = k_thread_spawn(tstack[2], STACK_SIZE,
|
||||
tmpool_alloc_wait_timeout, NULL, NULL, NULL,
|
||||
K_PRIO_PREEMPT(0), 0, 20);
|
||||
/*relinquish CPU for above threads to start */
|
||||
k_sleep(30);
|
||||
/*free one block, expected to unblock thread "tid[1]"*/
|
||||
k_mem_pool_free(&block[0]);
|
||||
/*wait for all threads exit*/
|
||||
for (int i = 0; i < THREAD_NUM; i++) {
|
||||
k_sem_take(&sync_sema, K_FOREVER);
|
||||
}
|
||||
|
||||
/*test case tear down*/
|
||||
for (int i = 0; i < THREAD_NUM; i++) {
|
||||
k_thread_abort(tid[i]);
|
||||
}
|
||||
k_mem_pool_free(&block_ok);
|
||||
for (int i = 1; i < BLK_NUM_MIN; i++) {
|
||||
k_mem_pool_free(&block[i]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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 <ztest.h>
|
||||
#include "test_mpool.h"
|
||||
|
||||
extern struct k_mem_pool mpool1;
|
||||
|
||||
/*test cases*/
|
||||
void test_mpool_alloc_merge_failed_diff_parent(void)
|
||||
{
|
||||
struct k_mem_block block[BLK_NUM_MIN], block_fail;
|
||||
|
||||
/**
|
||||
* TESTPOINT: nor can it merge adjacent free blocks of the same
|
||||
* size if they belong to different parent quad-blocks
|
||||
* Test steps: 1. allocate block [0~7] in minimum block size
|
||||
* 2. free block [2~5], belong to diff parental quad-blocks
|
||||
* 3. request a big block
|
||||
* verify blocks [2, 3] and blocks [4, 5] can't be merged
|
||||
* 4. tear down, free blocks [0, 1, 6, 7]
|
||||
*/
|
||||
for (int i = 0; i < BLK_NUM_MIN; i++) {
|
||||
/* 1. allocated up all blocks*/
|
||||
assert_true(k_mem_pool_alloc(&mpool1, &block[i], BLK_SIZE_MIN,
|
||||
K_NO_WAIT) == 0, NULL);
|
||||
}
|
||||
/* 2. free adjacent blocks belong to different parent quad-blocks*/
|
||||
for (int i = 2; i < 6; i++) {
|
||||
k_mem_pool_free(&block[i]);
|
||||
}
|
||||
/* 3. request a big block, expected failed to merge*/
|
||||
k_mem_pool_defrag(&mpool1);
|
||||
assert_true(k_mem_pool_alloc(&mpool1, &block_fail, BLK_SIZE_MAX,
|
||||
TIMEOUT) == -EAGAIN, NULL);
|
||||
|
||||
/* 4. test case tear down*/
|
||||
k_mem_pool_free(&block[0]);
|
||||
k_mem_pool_free(&block[1]);
|
||||
k_mem_pool_free(&block[6]);
|
||||
k_mem_pool_free(&block[7]);
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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 <ztest.h>
|
||||
#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(mpool3, BLK_SIZE_MIN, BLK_SIZE_MAX, BLK_NUM_MAX, BLK_ALIGN);
|
||||
|
||||
/*test cases*/
|
||||
void test_mpool_alloc_merge_failed_diff_size(void)
|
||||
{
|
||||
struct k_mem_block block[BLK_NUM_MIN], block_fail;
|
||||
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,
|
||||
BLK_SIZE_MIN, BLK_SIZE_MIN, BLK_SIZE_MIN, BLK_SIZE_MIN,
|
||||
BLK_SIZE_MID, BLK_SIZE_MID, BLK_SIZE_MID};
|
||||
int block_count = sizeof(block_size)/sizeof(size_t);
|
||||
|
||||
/**
|
||||
* TESTPOINT: the merging algorithm cannot combine adjacent free blocks
|
||||
* of different sizes
|
||||
* Test steps: 1. allocate 14 blocks in different sizes
|
||||
* 2. free block [2~8], in different sizes
|
||||
* 3. request a big block
|
||||
* verify blocks [2~8] can't be merged
|
||||
* 4. tear down, free blocks [0, 1, 9~13]
|
||||
*/
|
||||
for (int i = 0; i < block_count; i++) {
|
||||
/* 1. allocate blocks in different sizes*/
|
||||
assert_true(k_mem_pool_alloc(&mpool3, &block[i], block_size[i],
|
||||
K_NO_WAIT) == 0, NULL);
|
||||
}
|
||||
/* 2. free block [2~8], in different sizes*/
|
||||
for (int i = 2; i < 9; i++) {
|
||||
k_mem_pool_free(&block[i]);
|
||||
}
|
||||
/* 3. request a big block, expected failed to merge*/
|
||||
k_mem_pool_defrag(&mpool3);
|
||||
assert_true(k_mem_pool_alloc(&mpool3, &block_fail, BLK_SIZE_MAX,
|
||||
TIMEOUT) == -EAGAIN, NULL);
|
||||
|
||||
/* 4. test case tear down*/
|
||||
k_mem_pool_free(&block[0]);
|
||||
k_mem_pool_free(&block[1]);
|
||||
for (int i = 9; i < block_count; i++) {
|
||||
k_mem_pool_free(&block[i]);
|
||||
}
|
||||
}
|
2
tests/kernel/mem_pool/test_mpool_concept/testcase.ini
Normal file
2
tests/kernel/mem_pool/test_mpool_concept/testcase.ini
Normal file
|
@ -0,0 +1,2 @@
|
|||
[test]
|
||||
tags = kernel
|
Loading…
Add table
Add a link
Reference in a new issue