diff --git a/tests/kernel/mem_slab/test_mslab_concept/Makefile b/tests/kernel/mem_slab/test_mslab_concept/Makefile new file mode 100644 index 00000000000..e70a750a88d --- /dev/null +++ b/tests/kernel/mem_slab/test_mslab_concept/Makefile @@ -0,0 +1,4 @@ +BOARD ?= qemu_x86 +CONF_FILE = prj.conf + +include ${ZEPHYR_BASE}/Makefile.test diff --git a/tests/kernel/mem_slab/test_mslab_concept/prj.conf b/tests/kernel/mem_slab/test_mslab_concept/prj.conf new file mode 100644 index 00000000000..9467c292689 --- /dev/null +++ b/tests/kernel/mem_slab/test_mslab_concept/prj.conf @@ -0,0 +1 @@ +CONFIG_ZTEST=y diff --git a/tests/kernel/mem_slab/test_mslab_concept/src/Makefile b/tests/kernel/mem_slab/test_mslab_concept/src/Makefile new file mode 100644 index 00000000000..47b143c6743 --- /dev/null +++ b/tests/kernel/mem_slab/test_mslab_concept/src/Makefile @@ -0,0 +1,3 @@ +include $(ZEPHYR_BASE)/tests/Makefile.test + +obj-y = main.o test_mslab_alloc_wait.o diff --git a/tests/kernel/mem_slab/test_mslab_concept/src/main.c b/tests/kernel/mem_slab/test_mslab_concept/src/main.c new file mode 100644 index 00000000000..8fbe18dee1c --- /dev/null +++ b/tests/kernel/mem_slab/test_mslab_concept/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_mslab_alloc_wait_prio(void); + +/*test case main entry*/ +void test_main(void *p1, void *p2, void *p3) +{ + ztest_test_suite(test_mslab_concept, + ztest_unit_test(test_mslab_alloc_wait_prio)); + ztest_run_test_suite(test_mslab_concept); +} + diff --git a/tests/kernel/mem_slab/test_mslab_concept/src/test_mslab.h b/tests/kernel/mem_slab/test_mslab_concept/src/test_mslab.h new file mode 100644 index 00000000000..9710e4a3879 --- /dev/null +++ b/tests/kernel/mem_slab/test_mslab_concept/src/test_mslab.h @@ -0,0 +1,25 @@ +/* + * 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. + */ + +#ifndef __TEST_MSLAB_H__ +#define __TEST_MSLAB_H__ + +#define TIMEOUT 2000 +#define BLK_NUM 3 +#define BLK_ALIGN 4 +#define BLK_SIZE 8 + +#endif /*__TEST_MSLAB_H__*/ diff --git a/tests/kernel/mem_slab/test_mslab_concept/src/test_mslab_alloc_wait.c b/tests/kernel/mem_slab/test_mslab_concept/src/test_mslab_alloc_wait.c new file mode 100644 index 00000000000..dd228450a31 --- /dev/null +++ b/tests/kernel/mem_slab/test_mslab_concept/src/test_mslab_alloc_wait.c @@ -0,0 +1,118 @@ +/* + * 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_mslab + * @{ + * @defgroup t_mslab_concept test_mslab_concept + * @brief TestPurpose: verify memory slab 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 are covered in API test: + * - TESTPOINT: ensure that all memory blocks in the buffer are similarly + * aligned to this boundary + * - TESTPOINT: A memory slab must be initialized before it can be used. This + * marks all of its blocks as unused. + * + * TESTPOINTS related to multiple instances are covered in re-entrance test: + * - TESTPOINT: Unlike a heap, more than one memory slab can be defined, if + * needed. + * @} + */ + +#include +#include "test_mslab.h" + +#define THREAD_NUM 3 +#define STACK_SIZE 512 + +K_MEM_SLAB_DEFINE(mslab1, BLK_SIZE, BLK_NUM, BLK_ALIGN); + +static char __noinit __stack tstack[THREAD_NUM][STACK_SIZE]; +static struct k_sem sync_sema; +static void *block_ok; + +/*thread entry*/ +void tmslab_alloc_wait_timeout(void *p1, void *p2, void *p3) +{ + void *block; + + assert_true(k_mem_slab_alloc(&mslab1, &block, TIMEOUT) == -EAGAIN, + NULL); + k_sem_give(&sync_sema); +} + +void tmslab_alloc_wait_ok(void *p1, void *p2, void *p3) +{ + assert_true(k_mem_slab_alloc(&mslab1, &block_ok, TIMEOUT) == 0, NULL); + k_sem_give(&sync_sema); +} + +/*test cases*/ +void test_mslab_alloc_wait_prio(void) +{ + void *block[BLK_NUM]; + 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; i++) { + assert_equal(k_mem_slab_alloc(&mslab1, &block[i], K_NO_WAIT), + 0, NULL); + } + + /** + * TESTPOINT: Any number of threads may wait on an empty memory slab + * simultaneously; when a memory block becomes available, it is given to + * the highest-priority thread that has waited the longest. + */ + /** + * TESTPOINT: If all the blocks are currently in use, a thread can + * optionally wait for one to become available. + */ + /*the low-priority thread*/ + tid[0] = k_thread_spawn(tstack[0], STACK_SIZE, + tmslab_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, + tmslab_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, + tmslab_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_slab_free(&mslab1, &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_slab_free(&mslab1, &block_ok); + for (int i = 1; i < BLK_NUM; i++) { + k_mem_slab_free(&mslab1, &block[i]); + } +} diff --git a/tests/kernel/mem_slab/test_mslab_concept/testcase.ini b/tests/kernel/mem_slab/test_mslab_concept/testcase.ini new file mode 100644 index 00000000000..58c4d1a1747 --- /dev/null +++ b/tests/kernel/mem_slab/test_mslab_concept/testcase.ini @@ -0,0 +1,2 @@ +[test] +tags = kernel