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 <sharron.liu@intel.com>
This commit is contained in:
Sharron LIU 2016-12-30 12:32:06 +08:00
commit d7a9ac21ce
6 changed files with 131 additions and 0 deletions

View file

@ -0,0 +1,4 @@
BOARD ?= qemu_x86
CONF_FILE = prj.conf
include ${ZEPHYR_BASE}/Makefile.test

View file

@ -0,0 +1,4 @@
CONFIG_ZTEST=y
CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000
# 1 millisecond
CONFIG_TIMESLICE_SIZE=1

View file

@ -0,0 +1,3 @@
include $(ZEPHYR_BASE)/tests/Makefile.test
obj-y = main.o test_mslab_threadsafe.o

View file

@ -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 <ztest.h>
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);
}

View file

@ -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 <ztest.h>
#include <atomic.h>
#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]);
}
}

View file

@ -0,0 +1,2 @@
[test]
tags = kernel