rt-thread/examples/utest/testcases/mm/test_synchronization.h
Shell eec78d9f5d
[rt-smart] testcase & improvements for memory management (#7099)
* [utest/mm] add testcase for create/init
format codes of create/init in components/mm

* [libcpu/aarch64] fix user stack check routine

* [kservice] export API for utest

* [utest/mm] testcase for aspace_map
format & modify the files under components/mm related with aspace_map

* [lwp/user_mm] add user_map_varea for mmap feature

* [mm] rename rt_mm_fault_try_fix to rt_aspace_fault_try_fix

* [utest/mm] testcase for synchronization

* [mm] modify unmap api to improve throughput

* [utest/mm] testcases for cache and varea map

* [format] remove extra space

* [utest/mm] fix testcase problem in header

* [lwp] extend map_user_varea with a flag

* [utest/mm] testcase for lwp_map_user_varea

* [libcpu/arm/cortex-a] fix kernel space layout

* [utest/mm] adjust for armv7 arch
2023-03-30 08:25:15 +08:00

166 lines
3.7 KiB
C

/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-03-24 WangXiaoyao Complete testcase for synchronization
*/
#ifndef __TEST_SYNCHRONIZATION_H__
#define __TEST_SYNCHRONIZATION_H__
#include "common.h"
#include "semaphore.h"
#ifdef RT_USING_SMP
#define THREAD_CNT RT_CPUS_NR
#define TEST_TIMES 2000
#define PRIO (UTEST_THR_PRIORITY + 1)
/* size of mapping buffer */
#define BUF_SIZE (64ul << 10)
/* engage with sibling */
struct rt_semaphore done;
static semaphore_t sem1[THREAD_CNT / 2];
static semaphore_t sem2[THREAD_CNT / 2];
static void *map(void)
{
int err;
int flags = MMF_PREFETCH;
size_t attr = MMU_MAP_K_RWCB;
void *vaddr = 0;
err =
rt_aspace_map(&rt_kernel_space, &vaddr, BUF_SIZE, attr, flags, &rt_mm_dummy_mapper, 0);
if (err)
uassert_true(0);
return vaddr;
}
static void unmap(void *buf)
{
int err;
err =
rt_aspace_unmap(&rt_kernel_space, buf);
if (err)
uassert_true(0);
return ;
}
static void group1_entry(void *param)
{
const size_t id = (size_t)param;
size_t test_times = TEST_TIMES;
size_t alive = test_times / 10;
void *buf;
while (test_times--)
{
if (test_times % alive == 0)
uassert_true(1);
buf = map();
memset(buf, 'A' + id, BUF_SIZE);
/* if other core write to our cache, force the changes to be visible to us */
rt_hw_dmb();
if (memtest(buf, 'A' + id, BUF_SIZE))
uassert_true(0);
semaphore_signal(&sem1[id]);
semaphore_wait(&sem2[id]);
unmap(buf);
}
rt_sem_release(&done);
return;
}
static void group2_entry(void *param)
{
const size_t id = (size_t)param;
size_t test_times = TEST_TIMES;
size_t alive = test_times / 10;
void *buf;
while (test_times--)
{
if (test_times % alive == 0)
uassert_true(1);
semaphore_signal(&sem2[id]);
semaphore_wait(&sem1[id]);
buf = map();
memset(buf, 'a' + id, BUF_SIZE);
/* if other core write to our cache, force the changes to be visible to us */
rt_hw_dmb();
if (memtest(buf, 'a' + id, BUF_SIZE))
uassert_true(0);
unmap(buf);
}
rt_sem_release(&done);
return;
}
/**
* @brief On a smp system, we create at least 4 threads
* 2 doing map, 2 doing unmapping at the same moment
*/
static void synchronization_tc(void)
{
rt_thread_t group1[THREAD_CNT / 2];
rt_thread_t group2[THREAD_CNT / 2];
rt_sem_init(&done, __func__, 0, RT_IPC_FLAG_FIFO);
for (size_t i = 0; i < THREAD_CNT / 2; i++)
{
char name[RT_NAME_MAX];
rt_sprintf(name, "grp1_%d", i);
group1[i] =
rt_thread_create(name, group1_entry, (void *)i, ARCH_PAGE_SIZE, PRIO, 10);
uassert_true(!!group1[i]);
semaphore_init(&sem1[i], 0);
uassert_true(!rt_thread_startup(group1[i]));
}
for (size_t i = 0; i < THREAD_CNT / 2; i++)
{
char name[RT_NAME_MAX];
rt_sprintf(name, "grp2_%d", i);
group2[i] =
rt_thread_create(name, group2_entry, (void *)i, ARCH_PAGE_SIZE, PRIO, 10);
uassert_true(!!group2[i]);
semaphore_init(&sem2[i], 0);
uassert_true(!rt_thread_startup(group2[i]));
}
/* wait all thread exit */
for (size_t i = 0; i < (THREAD_CNT / 2 * 2); i++)
{
rt_sem_take(&done, RT_WAITING_FOREVER);
}
LOG_I("all threads exit");
rt_sem_detach(&done);
}
#else /* RT_USING_SMP */
static void synchronization_tc(void)
{
uassert_true(1);
}
#endif /* RT_USING_SMP */
#endif /* __TEST_SYNCHRONIZATION_H__ */