blob: 64e347e764af4750a85ad632e5823815e69e9ea3 [file] [log] [blame]
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @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]);
}
}