From d7a9ac21ce104cd09a6891371ffa4a5f55a4e32d Mon Sep 17 00:00:00 2001 From: Sharron LIU Date: Fri, 30 Dec 2016 12:32:06 +0800 Subject: [PATCH] tests: kernel: added memory slab threadsafe test TestPurpose: verify API thread safe in multi-threads environment. Thread safe test is explained with more details here: https://gerrit.zephyrproject.org/r/#/c/9464/7/ test_mpool_threadsafe.c Please comment if you think it necessary as an extensive kernel test. Jira: ZEP-1209 Change-Id: I52a7ff393d72785622c047289e7d92286e131cc7 Signed-off-by: Sharron LIU --- .../mem_slab/test_mslab_threadsafe/Makefile | 4 + .../mem_slab/test_mslab_threadsafe/prj.conf | 4 + .../test_mslab_threadsafe/src/Makefile | 3 + .../mem_slab/test_mslab_threadsafe/src/main.c | 27 ++++++ .../src/test_mslab_threadsafe.c | 91 +++++++++++++++++++ .../test_mslab_threadsafe/testcase.ini | 2 + 6 files changed, 131 insertions(+) create mode 100644 tests/kernel/mem_slab/test_mslab_threadsafe/Makefile create mode 100644 tests/kernel/mem_slab/test_mslab_threadsafe/prj.conf create mode 100644 tests/kernel/mem_slab/test_mslab_threadsafe/src/Makefile create mode 100644 tests/kernel/mem_slab/test_mslab_threadsafe/src/main.c create mode 100644 tests/kernel/mem_slab/test_mslab_threadsafe/src/test_mslab_threadsafe.c create mode 100644 tests/kernel/mem_slab/test_mslab_threadsafe/testcase.ini diff --git a/tests/kernel/mem_slab/test_mslab_threadsafe/Makefile b/tests/kernel/mem_slab/test_mslab_threadsafe/Makefile new file mode 100644 index 00000000000..e70a750a88d --- /dev/null +++ b/tests/kernel/mem_slab/test_mslab_threadsafe/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_threadsafe/prj.conf b/tests/kernel/mem_slab/test_mslab_threadsafe/prj.conf new file mode 100644 index 00000000000..a508d3161c6 --- /dev/null +++ b/tests/kernel/mem_slab/test_mslab_threadsafe/prj.conf @@ -0,0 +1,4 @@ +CONFIG_ZTEST=y +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 +# 1 millisecond +CONFIG_TIMESLICE_SIZE=1 diff --git a/tests/kernel/mem_slab/test_mslab_threadsafe/src/Makefile b/tests/kernel/mem_slab/test_mslab_threadsafe/src/Makefile new file mode 100644 index 00000000000..a280c4a17dd --- /dev/null +++ b/tests/kernel/mem_slab/test_mslab_threadsafe/src/Makefile @@ -0,0 +1,3 @@ +include $(ZEPHYR_BASE)/tests/Makefile.test + +obj-y = main.o test_mslab_threadsafe.o diff --git a/tests/kernel/mem_slab/test_mslab_threadsafe/src/main.c b/tests/kernel/mem_slab/test_mslab_threadsafe/src/main.c new file mode 100644 index 00000000000..66212319b95 --- /dev/null +++ b/tests/kernel/mem_slab/test_mslab_threadsafe/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_threadsafe(void); + +/*test case main entry*/ +void test_main(void *p1, void *p2, void *p3) +{ + ztest_test_suite(test_mslab_threadsafe, + ztest_unit_test(test_mslab_threadsafe)); + ztest_run_test_suite(test_mslab_threadsafe); +} diff --git a/tests/kernel/mem_slab/test_mslab_threadsafe/src/test_mslab_threadsafe.c b/tests/kernel/mem_slab/test_mslab_threadsafe/src/test_mslab_threadsafe.c new file mode 100644 index 00000000000..3e9703cacd5 --- /dev/null +++ b/tests/kernel/mem_slab/test_mslab_threadsafe/src/test_mslab_threadsafe.c @@ -0,0 +1,91 @@ +/* + * 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_threadsafe test_mslab_threadsafe + * @brief TestPurpose: verify API thread safe in multi-threads environment + * @} + */ + +#include +#include +#define LOOP 10 +#define STACK_SIZE 512 +#define THREAD_NUM 4 +#define SLAB_NUM 2 +#define TIMEOUT 200 +#define BLK_NUM 3 +#define BLK_ALIGN 4 +#define BLK_SIZE1 8 +#define BLK_SIZE2 4 + +K_MEM_SLAB_DEFINE(mslab1, BLK_SIZE1, BLK_NUM, BLK_ALIGN); +static struct k_mem_slab mslab2, *slabs[SLAB_NUM] = {&mslab1, &mslab2}; +static char __noinit __stack tstack[THREAD_NUM][STACK_SIZE]; +static char __aligned(BLK_ALIGN) tslab[BLK_SIZE2 * BLK_NUM]; +static struct k_sem sync_sema; +static atomic_t slab_id; + +/* thread entry simply invoke the APIs*/ +static void tmslab_api(void *p1, void *p2, void *p3) +{ + void *block[BLK_NUM]; + struct k_mem_slab *slab = slabs[atomic_inc(&slab_id) % SLAB_NUM]; + int i = LOOP; + + while (i--) { + memset(block, 0, sizeof(block)); + + for (int i = 0; i < BLK_NUM; i++) { + k_mem_slab_alloc(slab, &block[i], TIMEOUT); + } + for (int i = 0; i < BLK_NUM; i++) { + if (block[i]) { + k_mem_slab_free(slab, &block[i]); + block[i] = NULL; + } + } + } + + k_sem_give(&sync_sema); +} + +/* test cases*/ +void test_mslab_threadsafe(void) +{ + k_tid_t tid[THREAD_NUM]; + + k_mem_slab_init(&mslab2, tslab, BLK_SIZE2, BLK_NUM); + k_sem_init(&sync_sema, 0, THREAD_NUM); + + /* create multiple threads to invoke same memory slab APIs*/ + for (int i = 0; i < THREAD_NUM; i++) { + tid[i] = k_thread_spawn(tstack[i], STACK_SIZE, + tmslab_api, NULL, NULL, NULL, + K_PRIO_PREEMPT(1), 0, 0); + } + /* TESTPOINT: all threads complete and exit the entry function*/ + 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]); + } +} diff --git a/tests/kernel/mem_slab/test_mslab_threadsafe/testcase.ini b/tests/kernel/mem_slab/test_mslab_threadsafe/testcase.ini new file mode 100644 index 00000000000..58c4d1a1747 --- /dev/null +++ b/tests/kernel/mem_slab/test_mslab_threadsafe/testcase.ini @@ -0,0 +1,2 @@ +[test] +tags = kernel