123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- /*
- * 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__ */
|