import RT-Thread@9217865c without bsp, libcpu and components/net

This commit is contained in:
Zihao Yu 2023-05-20 16:23:33 +08:00
commit e2376a3709
1414 changed files with 390370 additions and 0 deletions

View file

@ -0,0 +1,62 @@
menu "Kernel Testcase"
config UTEST_MEMHEAP_TC
bool "memheap stability test"
default y
depends on RT_USING_MEMHEAP
config UTEST_SMALL_MEM_TC
bool "mem test"
default y
depends on RT_USING_SMALL_MEM
config UTEST_SLAB_TC
bool "slab test"
default n
depends on RT_USING_SLAB
config UTEST_IRQ_TC
bool "IRQ test"
default n
config UTEST_SEMAPHORE_TC
bool "semaphore test"
default n
depends on RT_USING_SEMAPHORE
config UTEST_EVENT_TC
bool "event test"
default n
depends on RT_USING_EVENT
config UTEST_TIMER_TC
bool "timer test"
default n
config UTEST_MESSAGEQUEUE_TC
bool "message queue test"
default n
config UTEST_SIGNAL_TC
bool "signal test"
default n
config UTEST_MUTEX_TC
bool "mutex test"
default n
config UTEST_MAILBOX_TC
bool "mailbox test"
default n
config UTEST_THREAD_TC
bool "thread test"
default n
select RT_USING_TIMER_SOFT
select RT_USING_THREAD
config UTEST_ATOMIC_TC
bool "atomic test"
default n
endmenu

View file

@ -0,0 +1,49 @@
Import('rtconfig')
from building import *
cwd = GetCurrentDir()
src = []
CPPPATH = [cwd]
if GetDepend(['UTEST_MEMHEAP_TC']):
src += ['memheap_tc.c']
if GetDepend(['UTEST_SMALL_MEM_TC']):
src += ['mem_tc.c']
if GetDepend(['UTEST_SLAB_TC']):
src += ['slab_tc.c']
if GetDepend(['UTEST_IRQ_TC']):
src += ['irq_tc.c']
if GetDepend(['UTEST_SEMAPHORE_TC']):
src += ['semaphore_tc.c']
if GetDepend(['UTEST_EVENT_TC']):
src += ['event_tc.c']
if GetDepend(['UTEST_TIMER_TC']):
src += ['timer_tc.c']
if GetDepend(['UTEST_MESSAGEQUEUE_TC']):
src += ['messagequeue_tc.c']
if GetDepend(['UTEST_SIGNAL_TC']):
src += ['signal_tc.c']
if GetDepend(['UTEST_MUTEX_TC']):
src += ['mutex_tc.c']
if GetDepend(['UTEST_MAILBOX_TC']):
src += ['mailbox_tc.c']
if GetDepend(['UTEST_THREAD_TC']):
src += ['thread_tc.c']
if GetDepend(['UTEST_ATOMIC_TC']):
src += ['atomic_tc.c']
group = DefineGroup('utestcases', src, depend = ['RT_USING_UTESTCASES'], CPPPATH = CPPPATH)
Return('group')

View file

@ -0,0 +1,170 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-07-27 flybreak the first version
* 2023-03-21 WangShun add atomic test
*/
#include <rtthread.h>
#include "utest.h"
#include "rtatomic.h"
#include <rthw.h>
#define THREAD_PRIORITY 25
#define THREAD_TIMESLICE 1
#define THREAD_STACKSIZE 1024
/* convenience macro - return either 64-bit or 32-bit value */
#define ATOMIC_WORD(val_if_64, val_if_32) \
((rt_atomic_t)((sizeof(void *) == sizeof(uint64_t)) ? (val_if_64) : (val_if_32)))
static rt_atomic_t count = 0;
static rt_sem_t sem_t;
static void test_atomic_api(void)
{
rt_atomic_t base;
rt_atomic_t oldval;
rt_atomic_t result;
/* rt_atomic_t */
uassert_true(sizeof(rt_atomic_t) == ATOMIC_WORD(sizeof(uint64_t), sizeof(uint32_t)));
/* rt_atomic_add */
base = 0;
result = rt_atomic_add(&base, 10);
uassert_true(base == 10);
uassert_true(result == 0);
/* rt_atomic_add negative */
base = 2;
result = rt_atomic_add(&base, -4);
uassert_true(base == -2);
uassert_true(result == 2);
/* rt_atomic_sub */
base = 11;
result = rt_atomic_sub(&base, 10);
uassert_true(base == 1);
uassert_true(result == 11);
/* rt_atomic_sub negative */
base = 2;
result = rt_atomic_sub(&base, -5);
uassert_true(base == 7);
uassert_true(result == 2);
/* rt_atomic_or */
base = 0xFF00;
result = rt_atomic_or(&base, 0x0F0F);
uassert_true(base == 0xFF0F);
uassert_true(result == 0xFF00);
/* rt_atomic_xor */
base = 0xFF00;
result = rt_atomic_xor(&base, 0x0F0F);
uassert_true(base == 0xF00F);
uassert_true(result == 0xFF00);
/* rt_atomic_and */
base = 0xFF00;
result = rt_atomic_and(&base, 0x0F0F);
uassert_true(base == 0x0F00);
uassert_true(result == 0xFF00);
/* rt_atomic_exchange */
base = 0xFF00;
result = rt_atomic_exchange(&base, 0x0F0F);
uassert_true(base == 0x0F0F);
uassert_true(result == 0xFF00);
/* rt_atomic_flag_test_and_set (Flag 0) */
base = 0x0;
result = rt_atomic_flag_test_and_set(&base);
uassert_true(base == 0x1);
uassert_true(result == 0x0);
/* rt_atomic_flag_test_and_set (Flag 1) */
base = 0x1;
result = rt_atomic_flag_test_and_set(&base);
uassert_true(base == 0x1);
uassert_true(result == 0x1);
/* rt_atomic_flag_clear */
base = 0x1;
rt_atomic_flag_clear(&base);
uassert_true(base == 0x0);
/* rt_atomic_load */
base = 0xFF00;
result = rt_atomic_load(&base);
uassert_true(base == 0xFF00);
uassert_true(result == 0xFF00);
/* rt_atomic_store */
base = 0xFF00;
rt_atomic_store(&base, 0x0F0F);
uassert_true(base == 0x0F0F);
/* rt_atomic_compare_exchange_strong (equal) */
base = 10;
oldval = 10;
result = rt_atomic_compare_exchange_strong(&base, &oldval, 11);
uassert_true(base == 11);
uassert_true(result == 0x1);
/* rt_atomic_compare_exchange_strong (not equal) */
base = 10;
oldval = 5;
result = rt_atomic_compare_exchange_strong(&base, &oldval, 11);
uassert_true(base == 10);
uassert_true(result == 0x0);
}
static void ture_entry(void *parameter)
{
int i;
for (i = 0; i < 1000000; i++)
{
rt_atomic_add(&count, 1);
}
rt_sem_release(sem_t);
}
static void test_atomic_add(void)
{
rt_thread_t thread;
int i;
sem_t = rt_sem_create("atomic_sem", 0, RT_IPC_FLAG_PRIO);
count = 0;
thread = rt_thread_create("t1", ture_entry, RT_NULL, THREAD_STACKSIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
rt_thread_startup(thread);
thread = rt_thread_create("t2", ture_entry, RT_NULL, THREAD_STACKSIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
rt_thread_startup(thread);
thread = rt_thread_create("t3", ture_entry, RT_NULL, THREAD_STACKSIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
rt_thread_startup(thread);
for (i = 0; i < 3; i++)
{
rt_sem_take(sem_t, RT_WAITING_FOREVER);
}
uassert_true(count == 3000000);
}
static rt_err_t utest_tc_init(void)
{
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
return RT_EOK;
}
static void testcase(void)
{
UTEST_UNIT_RUN(test_atomic_api);
UTEST_UNIT_RUN(test_atomic_add);
}
UTEST_TC_EXPORT(testcase, "testcases.kernel.atomic_tc", utest_tc_init, utest_tc_cleanup, 10);

View file

@ -0,0 +1,344 @@
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-08-15 liukang the first version
*/
#include <rtthread.h>
#include "utest.h"
#include <stdlib.h>
#define EVENT_FLAG3 (1 << 3)
#define EVENT_FLAG5 (1 << 5)
static struct rt_event static_event = {0};
#ifdef RT_USING_HEAP
static rt_event_t dynamic_event = RT_NULL;
static rt_uint32_t dynamic_event_recv_thread_finish = 0, dynamic_event_send_thread_finish = 0;
rt_align(RT_ALIGN_SIZE)
static char thread3_stack[1024];
static struct rt_thread thread3;
rt_align(RT_ALIGN_SIZE)
static char thread4_stack[1024];
static struct rt_thread thread4;
#endif /* RT_USING_HEAP */
static rt_uint32_t recv_event_times1 = 0, recv_event_times2 = 0;
static rt_uint32_t static_event_recv_thread_finish = 0, static_event_send_thread_finish = 0;
rt_align(RT_ALIGN_SIZE)
static char thread1_stack[1024];
static struct rt_thread thread1;
rt_align(RT_ALIGN_SIZE)
static char thread2_stack[1024];
static struct rt_thread thread2;
#define THREAD_PRIORITY 9
#define THREAD_TIMESLICE 5
static void test_event_init(void)
{
rt_err_t result;
result = rt_event_init(&static_event, "event", RT_IPC_FLAG_PRIO);
if (result != RT_EOK)
{
uassert_false(1);
}
result = rt_event_detach(&static_event);
if (result != RT_EOK)
{
uassert_false(1);
}
result = rt_event_init(&static_event, "event", RT_IPC_FLAG_FIFO);
if (result != RT_EOK)
{
uassert_false(1);
}
result = rt_event_detach(&static_event);
if (result != RT_EOK)
{
uassert_false(1);
}
uassert_true(1);
}
static void test_event_detach(void)
{
rt_err_t result = RT_EOK;
result = rt_event_init(&static_event, "event", RT_IPC_FLAG_PRIO);
if (result != RT_EOK)
{
uassert_false(1);
}
result = rt_event_detach(&static_event);
if (result != RT_EOK)
{
uassert_false(1);
}
uassert_true(1);
}
static void thread1_recv_static_event(void *param)
{
rt_uint32_t e;
if (rt_event_recv(&static_event, (EVENT_FLAG3 | EVENT_FLAG5),
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
RT_WAITING_FOREVER, &e) != RT_EOK)
{
return;
}
recv_event_times1 = e;
rt_thread_mdelay(50);
if (rt_event_recv(&static_event, (EVENT_FLAG3 | EVENT_FLAG5),
RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,
RT_WAITING_FOREVER, &e) != RT_EOK)
{
return;
}
recv_event_times2 = e;
static_event_recv_thread_finish = 1;
}
static void thread2_send_static_event(void *param)
{
rt_event_send(&static_event, EVENT_FLAG3);
rt_thread_mdelay(10);
rt_event_send(&static_event, EVENT_FLAG5);
rt_thread_mdelay(10);
rt_event_send(&static_event, EVENT_FLAG3);
static_event_send_thread_finish = 1;
}
static void test_static_event_send_recv(void)
{
rt_err_t result = RT_EOK;
result = rt_event_init(&static_event, "event", RT_IPC_FLAG_PRIO);
if (result != RT_EOK)
{
uassert_false(1);
}
rt_thread_init(&thread1,
"thread1",
thread1_recv_static_event,
RT_NULL,
&thread1_stack[0],
sizeof(thread1_stack),
THREAD_PRIORITY - 1, THREAD_TIMESLICE);
rt_thread_startup(&thread1);
rt_thread_init(&thread2,
"thread2",
thread2_send_static_event,
RT_NULL,
&thread2_stack[0],
sizeof(thread2_stack),
THREAD_PRIORITY, THREAD_TIMESLICE);
rt_thread_startup(&thread2);
while (static_event_recv_thread_finish != 1 || static_event_send_thread_finish != 1)
{
rt_thread_delay(1);
}
if (recv_event_times1 == EVENT_FLAG3 && recv_event_times2 == (EVENT_FLAG3 | EVENT_FLAG5))
{
if (rt_event_detach(&static_event) != RT_EOK)
{
uassert_false(1);
}
uassert_true(1);
}
else
{
if (rt_event_detach(&static_event) != RT_EOK)
{
uassert_false(1);
}
uassert_false(1);
}
return;
}
#ifdef RT_USING_HEAP
static void test_event_create(void)
{
rt_err_t result = RT_EOK;
dynamic_event = rt_event_create("dynamic_event", RT_IPC_FLAG_FIFO);
if (dynamic_event == RT_NULL)
{
uassert_false(1);
}
result = rt_event_delete(dynamic_event);
if (result != RT_EOK)
{
uassert_false(1);
}
uassert_true(1);
}
static void test_event_delete(void)
{
rt_err_t result;
dynamic_event = rt_event_create("dynamic_event", RT_IPC_FLAG_FIFO);
if (dynamic_event == RT_NULL)
{
uassert_false(1);
}
result = rt_event_delete(dynamic_event);
if (result != RT_EOK)
{
uassert_false(1);
}
uassert_true(1);
}
static void thread3_recv_dynamic_event(void *param)
{
rt_uint32_t e;
if (rt_event_recv(dynamic_event, (EVENT_FLAG3 | EVENT_FLAG5),
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
RT_WAITING_FOREVER, &e) != RT_EOK)
{
return;
}
recv_event_times1 = e;
rt_thread_mdelay(50);
if (rt_event_recv(dynamic_event, (EVENT_FLAG3 | EVENT_FLAG5),
RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,
RT_WAITING_FOREVER, &e) != RT_EOK)
{
return;
}
recv_event_times2 = e;
dynamic_event_recv_thread_finish = 1;
}
static void thread4_send_dynamic_event(void *param)
{
rt_event_send(dynamic_event, EVENT_FLAG3);
rt_thread_mdelay(10);
rt_event_send(dynamic_event, EVENT_FLAG5);
rt_thread_mdelay(10);
rt_event_send(dynamic_event, EVENT_FLAG3);
dynamic_event_send_thread_finish = 1;
}
static void test_dynamic_event_send_recv(void)
{
dynamic_event = rt_event_create("dynamic_event", RT_IPC_FLAG_PRIO);
if (dynamic_event == RT_NULL)
{
uassert_false(1);
}
rt_thread_init(&thread3,
"thread3",
thread3_recv_dynamic_event,
RT_NULL,
&thread3_stack[0],
sizeof(thread3_stack),
THREAD_PRIORITY - 1, THREAD_TIMESLICE);
rt_thread_startup(&thread3);
rt_thread_init(&thread4,
"thread4",
thread4_send_dynamic_event,
RT_NULL,
&thread4_stack[0],
sizeof(thread4_stack),
THREAD_PRIORITY, THREAD_TIMESLICE);
rt_thread_startup(&thread4);
while (dynamic_event_recv_thread_finish != 1 || dynamic_event_send_thread_finish != 1)
{
rt_thread_delay(1);
}
if (recv_event_times1 == EVENT_FLAG3 && recv_event_times2 == (EVENT_FLAG3 | EVENT_FLAG5))
{
if (rt_event_delete(dynamic_event) != RT_EOK)
{
uassert_false(1);
}
uassert_true(1);
}
else
{
if (rt_event_delete(dynamic_event) != RT_EOK)
{
uassert_false(1);
}
uassert_false(1);
}
return;
}
#endif
static rt_err_t utest_tc_init(void)
{
static_event_recv_thread_finish = 0;
static_event_send_thread_finish = 0;
#ifdef RT_USING_HEAP
dynamic_event_recv_thread_finish = 0;
dynamic_event_send_thread_finish = 0;
#endif
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
return RT_EOK;
}
static void testcase(void)
{
UTEST_UNIT_RUN(test_event_init);
UTEST_UNIT_RUN(test_event_detach);
UTEST_UNIT_RUN(test_static_event_send_recv);
#ifdef RT_USING_HEAP
UTEST_UNIT_RUN(test_event_create);
UTEST_UNIT_RUN(test_event_delete);
UTEST_UNIT_RUN(test_dynamic_event_send_recv);
#endif
}
UTEST_TC_EXPORT(testcase, "src.ipc.event_tc", utest_tc_init, utest_tc_cleanup, 60);

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-08-15 supperthomas add irq_test
*/
#include <rtthread.h>
#include "utest.h"
#include "rthw.h"
#define UTEST_NAME "irq_tc"
static uint32_t irq_count = 0;
static uint32_t max_get_nest_count = 0;
static void irq_callback()
{
if(rt_interrupt_get_nest() > max_get_nest_count)
{
max_get_nest_count = rt_interrupt_get_nest();
}
irq_count ++;
}
static void irq_test(void)
{
irq_count = 0;
rt_interrupt_enter_sethook(irq_callback);
rt_interrupt_leave_sethook(irq_callback);
rt_thread_mdelay(2);
LOG_D("%s test irq_test! irq_count %d max_get_nest_count %d\n", UTEST_NAME, irq_count, max_get_nest_count);
uassert_int_not_equal(0, irq_count);
uassert_int_not_equal(0, max_get_nest_count);
rt_interrupt_enter_sethook(RT_NULL);
rt_interrupt_leave_sethook(RT_NULL);
LOG_D("irq_test OK!\n");
}
static rt_err_t utest_tc_init(void)
{
irq_count = 0;
max_get_nest_count = 0;
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
return RT_EOK;
}
static void interrupt_test(void)
{
rt_base_t level;
uint32_t i = 1000;
rt_interrupt_enter_sethook(irq_callback);
rt_interrupt_leave_sethook(irq_callback);
irq_count = 0;
level = rt_hw_interrupt_disable();
while(i)
{
i --;
}
uassert_int_equal(0, irq_count);
rt_hw_interrupt_enable(level);
rt_interrupt_enter_sethook(RT_NULL);
rt_interrupt_leave_sethook(RT_NULL);
}
static void testcase(void)
{
UTEST_UNIT_RUN(irq_test);
UTEST_UNIT_RUN(interrupt_test);
}
UTEST_TC_EXPORT(testcase, "testcases.kernel.irq_tc", utest_tc_init, utest_tc_cleanup, 10);

View file

@ -0,0 +1,371 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-09-08 liukang the first version
*/
#include <rtthread.h>
#include "utest.h"
#include <stdlib.h>
static struct rt_mailbox test_static_mb;
static char mb_pool[128];
static rt_mailbox_t test_dynamic_mb;
static uint8_t static_mb_recv_thread_finish, static_mb_send_thread_finish;
static uint8_t dynamic_mb_recv_thread_finish, dynamic_mb_send_thread_finish;
rt_align(RT_ALIGN_SIZE)
static char thread1_stack[1024];
static struct rt_thread thread1;
rt_align(RT_ALIGN_SIZE)
static char thread2_stack[1024];
static struct rt_thread thread2;
#define THREAD_PRIORITY 9
#define THREAD_TIMESLICE 5
static rt_thread_t mb_send = RT_NULL;
static rt_thread_t mb_recv = RT_NULL;
static rt_uint8_t mb_send_str1[] = "this is first mail!";
static rt_uint8_t mb_send_str2[] = "this is second mail!";
static rt_uint8_t mb_send_str3[] = "this is thirdy mail!";
static rt_uint8_t *mb_recv_str1;
static rt_uint8_t *mb_recv_str2;
static rt_uint8_t *mb_recv_str3;
static void test_mailbox_init(void)
{
rt_err_t result;
result = rt_mb_init(&test_static_mb, "mbt", &mb_pool[0], sizeof(mb_pool) / 4, RT_IPC_FLAG_FIFO);
if (result != RT_EOK)
{
uassert_false(1);
}
result = rt_mb_detach(&test_static_mb);
if (result != RT_EOK)
{
uassert_false(1);
}
result = rt_mb_init(&test_static_mb, "mbt", &mb_pool[0], sizeof(mb_pool) / 4, RT_IPC_FLAG_PRIO);
if (result != RT_EOK)
{
uassert_false(1);
}
result = rt_mb_detach(&test_static_mb);
if (result != RT_EOK)
{
uassert_false(1);
}
uassert_true(1);
}
static void test_mailbox_deatch(void)
{
rt_err_t result;
result = rt_mb_init(&test_static_mb, "mbt", &mb_pool[0], sizeof(mb_pool) / 4, RT_IPC_FLAG_FIFO);
if (result != RT_EOK)
{
uassert_false(1);
}
result = rt_mb_detach(&test_static_mb);
if (result != RT_EOK)
{
uassert_false(1);
}
result = rt_mb_init(&test_static_mb, "mbt", &mb_pool[0], sizeof(mb_pool) / 4, RT_IPC_FLAG_PRIO);
if (result != RT_EOK)
{
uassert_false(1);
}
result = rt_mb_detach(&test_static_mb);
if (result != RT_EOK)
{
uassert_false(1);
}
uassert_true(1);
}
static void test_mailbox_create(void)
{
rt_err_t result;
test_dynamic_mb = rt_mb_create("test_dynamic_mb", sizeof(mb_pool) / 4, RT_IPC_FLAG_FIFO);
if (test_dynamic_mb == RT_NULL)
{
uassert_false(1);
}
result = rt_mb_delete(test_dynamic_mb);
if (result != RT_EOK)
{
uassert_false(1);
}
test_dynamic_mb = rt_mb_create("test_dynamic_mb", sizeof(mb_pool) / 4, RT_IPC_FLAG_PRIO);
if (test_dynamic_mb == RT_NULL)
{
uassert_false(1);
}
result = rt_mb_delete(test_dynamic_mb);
if (result != RT_EOK)
{
uassert_false(1);
}
uassert_true(1);
}
static void test_mailbox_delete(void)
{
rt_err_t result;
test_dynamic_mb = rt_mb_create("test_dynamic_mb", sizeof(mb_pool) / 4, RT_IPC_FLAG_FIFO);
if (test_dynamic_mb == RT_NULL)
{
uassert_false(1);
}
result = rt_mb_delete(test_dynamic_mb);
if (result != RT_EOK)
{
uassert_false(1);
}
test_dynamic_mb = rt_mb_create("test_dynamic_mb", sizeof(mb_pool) / 4, RT_IPC_FLAG_PRIO);
if (test_dynamic_mb == RT_NULL)
{
uassert_false(1);
}
result = rt_mb_delete(test_dynamic_mb);
if (result != RT_EOK)
{
uassert_false(1);
}
uassert_true(1);
}
static void thread2_send_static_mb(void *arg)
{
rt_err_t res = RT_EOK;
res = rt_mb_send(&test_static_mb, (rt_ubase_t)&mb_send_str1);
if (res != RT_EOK)
{
uassert_false(1);
}
rt_thread_mdelay(100);
res = rt_mb_send_wait(&test_static_mb, (rt_ubase_t)&mb_send_str2, 10);
if (res != RT_EOK)
{
uassert_false(1);
}
rt_thread_mdelay(100);
res = rt_mb_urgent(&test_static_mb, (rt_ubase_t)&mb_send_str3);
if (res != RT_EOK)
{
uassert_false(1);
}
static_mb_send_thread_finish = 1;
}
static void thread1_recv_static_mb(void *arg)
{
rt_err_t result = RT_EOK;
result = rt_mb_recv(&test_static_mb, (rt_ubase_t *)&mb_recv_str1, RT_WAITING_FOREVER);
if (result != RT_EOK || rt_strcmp((const char *)mb_recv_str1, (const char *)mb_send_str1) != 0)
{
uassert_false(1);
}
result = rt_mb_recv(&test_static_mb, (rt_ubase_t *)&mb_recv_str2, RT_WAITING_FOREVER);
if (result != RT_EOK || rt_strcmp((const char *)mb_recv_str2, (const char *)mb_send_str2) != 0)
{
uassert_false(1);
}
result = rt_mb_recv(&test_static_mb, (rt_ubase_t *)&mb_recv_str3, RT_WAITING_FOREVER);
if (result != RT_EOK || rt_strcmp((const char *)mb_recv_str3, (const char *)mb_send_str3) != 0)
{
uassert_false(1);
}
static_mb_recv_thread_finish = 1;
}
static void test_static_mailbox_send_recv(void)
{
rt_err_t result;
result = rt_mb_init(&test_static_mb, "mbt", &mb_pool[0], sizeof(mb_pool) / 4, RT_IPC_FLAG_FIFO);
if (result != RT_EOK)
{
uassert_false(1);
}
rt_thread_init(&thread1,
"thread1",
thread1_recv_static_mb,
RT_NULL,
&thread1_stack[0],
sizeof(thread1_stack),
THREAD_PRIORITY - 1, THREAD_TIMESLICE);
rt_thread_startup(&thread1);
rt_thread_init(&thread2,
"thread2",
thread2_send_static_mb,
RT_NULL,
&thread2_stack[0],
sizeof(thread2_stack),
THREAD_PRIORITY, THREAD_TIMESLICE);
rt_thread_startup(&thread2);
while (static_mb_recv_thread_finish != 1 || static_mb_send_thread_finish != 1)
{
rt_thread_delay(1);
}
if (rt_mb_detach(&test_static_mb) != RT_EOK)
{
uassert_false(1);
}
uassert_true(1);
}
static void thread4_send_dynamic_mb(void *arg)
{
rt_err_t res = RT_EOK;
res = rt_mb_send(test_dynamic_mb, (rt_ubase_t)&mb_send_str1);
if (res != RT_EOK)
{
uassert_false(1);
}
rt_thread_mdelay(100);
res = rt_mb_send_wait(test_dynamic_mb, (rt_ubase_t)&mb_send_str2, 10);
if (res != RT_EOK)
{
uassert_false(1);
}
rt_thread_mdelay(100);
res = rt_mb_urgent(test_dynamic_mb, (rt_ubase_t)&mb_send_str3);
if (res != RT_EOK)
{
uassert_false(1);
}
dynamic_mb_send_thread_finish = 1;
}
static void thread3_recv_dynamic_mb(void *arg)
{
rt_err_t result = RT_EOK;
result = rt_mb_recv(test_dynamic_mb, (rt_ubase_t *)&mb_recv_str1, RT_WAITING_FOREVER);
if (result != RT_EOK || rt_strcmp((const char *)mb_recv_str1, (const char *)mb_send_str1) != 0)
{
uassert_false(1);
}
result = rt_mb_recv(test_dynamic_mb, (rt_ubase_t *)&mb_recv_str2, RT_WAITING_FOREVER);
if (result != RT_EOK || rt_strcmp((const char *)mb_recv_str2, (const char *)mb_send_str2) != 0)
{
uassert_false(1);
}
result = rt_mb_recv(test_dynamic_mb, (rt_ubase_t *)&mb_recv_str3, RT_WAITING_FOREVER);
if (result != RT_EOK || rt_strcmp((const char *)mb_recv_str3, (const char *)mb_send_str3) != 0)
{
uassert_false(1);
}
dynamic_mb_recv_thread_finish = 1;
}
static void test_dynamic_mailbox_send_recv(void)
{
test_dynamic_mb = rt_mb_create("mbt", sizeof(mb_pool) / 4, RT_IPC_FLAG_FIFO);
if (test_dynamic_mb == RT_NULL)
{
uassert_false(1);
}
mb_recv = rt_thread_create("mb_recv_thread",
thread3_recv_dynamic_mb,
RT_NULL,
1024,
THREAD_PRIORITY - 1,
THREAD_TIMESLICE);
if (mb_recv == RT_NULL)
{
uassert_false(1);
}
rt_thread_startup(mb_recv);
mb_send = rt_thread_create("mb_send_thread",
thread4_send_dynamic_mb,
RT_NULL,
1024,
THREAD_PRIORITY - 1,
THREAD_TIMESLICE);
if (mb_send == RT_NULL)
{
uassert_false(1);
}
rt_thread_startup(mb_send);
while (dynamic_mb_recv_thread_finish != 1 || dynamic_mb_send_thread_finish != 1)
{
rt_thread_delay(1);
}
if (rt_mb_delete(test_dynamic_mb) != RT_EOK)
{
uassert_false(1);
}
uassert_true(1);
}
static rt_err_t utest_tc_init(void)
{
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
return RT_EOK;
}
static void testcase(void)
{
UTEST_UNIT_RUN(test_mailbox_init);
UTEST_UNIT_RUN(test_mailbox_deatch);
UTEST_UNIT_RUN(test_mailbox_create);
UTEST_UNIT_RUN(test_mailbox_delete);
UTEST_UNIT_RUN(test_static_mailbox_send_recv);
UTEST_UNIT_RUN(test_dynamic_mailbox_send_recv);
}
UTEST_TC_EXPORT(testcase, "src.ipc.mailbox_tc", utest_tc_init, utest_tc_cleanup, 60);

View file

@ -0,0 +1,588 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-14 tyx the first version
*/
#include <rtthread.h>
#include <stdlib.h>
#include "utest.h"
struct rt_small_mem_item
{
rt_ubase_t pool_ptr; /**< small memory object addr */
#ifdef ARCH_CPU_64BIT
rt_uint32_t resv;
#endif /* ARCH_CPU_64BIT */
rt_size_t next; /**< next free item */
rt_size_t prev; /**< prev free item */
#ifdef RT_USING_MEMTRACE
#ifdef ARCH_CPU_64BIT
rt_uint8_t thread[8]; /**< thread name */
#else
rt_uint8_t thread[4]; /**< thread name */
#endif /* ARCH_CPU_64BIT */
#endif /* RT_USING_MEMTRACE */
};
struct rt_small_mem
{
struct rt_memory parent; /**< inherit from rt_memory */
rt_uint8_t *heap_ptr; /**< pointer to the heap */
struct rt_small_mem_item *heap_end;
struct rt_small_mem_item *lfree;
rt_size_t mem_size_aligned; /**< aligned memory size */
};
#define MEM_SIZE(_heap, _mem) \
(((struct rt_small_mem_item *)(_mem))->next - ((rt_ubase_t)(_mem) - \
(rt_ubase_t)((_heap)->heap_ptr)) - RT_ALIGN(sizeof(struct rt_small_mem_item), RT_ALIGN_SIZE))
#define TEST_MEM_SIZE 1024
static rt_size_t max_block(struct rt_small_mem *heap)
{
struct rt_small_mem_item *mem;
rt_size_t max = 0, size;
for (mem = (struct rt_small_mem_item *)heap->heap_ptr;
mem != heap->heap_end;
mem = (struct rt_small_mem_item *)&heap->heap_ptr[mem->next])
{
if (((rt_ubase_t)mem->pool_ptr & 0x1) == 0)
{
size = MEM_SIZE(heap, mem);
if (size > max)
{
max = size;
}
}
}
return max;
}
static int _mem_cmp(void *ptr, rt_uint8_t v, rt_size_t size)
{
while (size-- != 0)
{
if (*(rt_uint8_t *)ptr != v)
return *(rt_uint8_t *)ptr - v;
}
return 0;
}
struct mem_test_context
{
void *ptr;
rt_size_t size;
rt_uint8_t magic;
};
static void mem_functional_test(void)
{
rt_size_t total_size;
rt_uint8_t *buf;
struct rt_small_mem *heap;
rt_uint8_t magic = __LINE__;
/* Prepare test memory */
buf = rt_malloc(TEST_MEM_SIZE);
uassert_not_null(buf);
uassert_int_equal(RT_ALIGN((rt_ubase_t)buf, RT_ALIGN_SIZE), (rt_ubase_t)buf);
rt_memset(buf, 0xAA, TEST_MEM_SIZE);
/* small heap init */
heap = (struct rt_small_mem *)rt_smem_init("mem_tc", buf, TEST_MEM_SIZE);
/* get total size */
total_size = max_block(heap);
uassert_int_not_equal(total_size, 0);
/*
* Allocate all memory at a time and test whether
* the memory allocation release function is effective
*/
{
struct mem_test_context ctx;
ctx.magic = magic++;
ctx.size = max_block(heap);
ctx.ptr = rt_smem_alloc(&heap->parent, ctx.size);
uassert_not_null(ctx.ptr);
rt_memset(ctx.ptr, ctx.magic, ctx.size);
uassert_int_equal(_mem_cmp(ctx.ptr, ctx.magic, ctx.size), 0);
rt_smem_free(ctx.ptr);
uassert_int_equal(max_block(heap), total_size);
}
/*
* Apply for memory release sequentially and
* test whether memory block merging is effective
*/
{
rt_size_t i, max_free = 0;
struct mem_test_context ctx[3];
/* alloc mem */
for (i = 0; i < sizeof(ctx) / sizeof(ctx[0]); i++)
{
ctx[i].magic = magic++;
ctx[i].size = max_block(heap) / (sizeof(ctx) / sizeof(ctx[0]) - i);
ctx[i].ptr = rt_smem_alloc(&heap->parent, ctx[i].size);
uassert_not_null(ctx[i].ptr);
rt_memset(ctx[i].ptr, ctx[i].magic, ctx[i].size);
}
/* All memory has been applied. The remaining memory should be 0 */
uassert_int_equal(max_block(heap), 0);
/* Verify that the memory data is correct */
for (i = 0; i < sizeof(ctx) / sizeof(ctx[0]); i++)
{
uassert_int_equal(_mem_cmp(ctx[i].ptr, ctx[i].magic, ctx[i].size), 0);
}
/* Sequential memory release */
for (i = 0; i < sizeof(ctx) / sizeof(ctx[0]); i++)
{
uassert_int_equal(_mem_cmp(ctx[i].ptr, ctx[i].magic, ctx[i].size), 0);
rt_smem_free(ctx[i].ptr);
max_free += ctx[i].size;
uassert_true(max_block(heap) >= max_free);
}
/* Check whether the memory is fully merged */
uassert_int_equal(max_block(heap), total_size);
}
/*
* Apply for memory release at an interval to
* test whether memory block merging is effective
*/
{
rt_size_t i, max_free = 0;
struct mem_test_context ctx[3];
/* alloc mem */
for (i = 0; i < sizeof(ctx) / sizeof(ctx[0]); i++)
{
ctx[i].magic = magic++;
ctx[i].size = max_block(heap) / (sizeof(ctx) / sizeof(ctx[0]) - i);
ctx[i].ptr = rt_smem_alloc(&heap->parent, ctx[i].size);
uassert_not_null(ctx[i].ptr);
rt_memset(ctx[i].ptr, ctx[i].magic, ctx[i].size);
}
/* All memory has been applied. The remaining memory should be 0 */
uassert_int_equal(max_block(heap), 0);
/* Verify that the memory data is correct */
for (i = 0; i < sizeof(ctx) / sizeof(ctx[0]); i++)
{
uassert_int_equal(_mem_cmp(ctx[i].ptr, ctx[i].magic, ctx[i].size), 0);
}
/* Release even address */
for (i = 0; i < sizeof(ctx) / sizeof(ctx[0]); i++)
{
if (i % 2 == 0)
{
uassert_int_equal(_mem_cmp(ctx[i].ptr, ctx[i].magic, ctx[i].size), 0);
rt_smem_free(ctx[i].ptr);
uassert_true(max_block(heap) >= ctx[0].size);
}
}
/* Release odd addresses and merge memory blocks */
for (i = 0; i < sizeof(ctx) / sizeof(ctx[0]); i++)
{
if (i % 2 != 0)
{
uassert_int_equal(_mem_cmp(ctx[i].ptr, ctx[i].magic, ctx[i].size), 0);
rt_smem_free(ctx[i].ptr);
max_free += ctx[i - 1].size + ctx[i + 1].size;
uassert_true(max_block(heap) >= max_free);
}
}
/* Check whether the memory is fully merged */
uassert_int_equal(max_block(heap), total_size);
}
/* mem realloc test,Small - > Large */
{
/* Request a piece of memory for subsequent reallocation operations */
struct mem_test_context ctx[3];
ctx[0].magic = magic++;
ctx[0].size = max_block(heap) / 3;
ctx[0].ptr = rt_smem_alloc(&heap->parent, ctx[0].size);
uassert_not_null(ctx[0].ptr);
rt_memset(ctx[0].ptr, ctx[0].magic, ctx[0].size);
/* Apply for a small piece of memory and split the continuous memory */
ctx[1].magic = magic++;
ctx[1].size = RT_ALIGN_SIZE;
ctx[1].ptr = rt_smem_alloc(&heap->parent, ctx[1].size);
uassert_not_null(ctx[1].ptr);
rt_memset(ctx[1].ptr, ctx[1].magic, ctx[1].size);
/* Check whether the maximum memory block is larger than the first piece of memory */
uassert_true(max_block(heap) > ctx[0].size);
/* Reallocate the first piece of memory */
ctx[2].magic = magic++;
ctx[2].size = max_block(heap);
ctx[2].ptr = rt_smem_realloc(&heap->parent, ctx[0].ptr, ctx[2].size);
uassert_not_null(ctx[2].ptr);
uassert_int_not_equal(ctx[0].ptr, ctx[2].ptr);
uassert_int_equal(_mem_cmp(ctx[2].ptr, ctx[0].magic, ctx[0].size), 0);
rt_memset(ctx[2].ptr, ctx[2].magic, ctx[2].size);
/* Free the second piece of memory */
uassert_int_equal(_mem_cmp(ctx[1].ptr, ctx[1].magic, ctx[1].size), 0);
rt_smem_free(ctx[1].ptr);
/* Free reallocated memory */
uassert_int_equal(_mem_cmp(ctx[2].ptr, ctx[2].magic, ctx[2].size), 0);
rt_smem_free(ctx[2].ptr);
/* Check memory integrity */
uassert_int_equal(max_block(heap), total_size);
}
/* mem realloc test,Large - > Small */
{
rt_size_t max_free;
struct mem_test_context ctx;
/* alloc a piece of memory */
ctx.magic = magic++;
ctx.size = max_block(heap) / 2;
ctx.ptr = rt_smem_alloc(&heap->parent, ctx.size);
uassert_not_null(ctx.ptr);
rt_memset(ctx.ptr, ctx.magic, ctx.size);
uassert_int_equal(_mem_cmp(ctx.ptr, ctx.magic, ctx.size), 0);
/* Get remaining memory */
max_free = max_block(heap);
/* Change memory size */
ctx.size = ctx.size / 2;
uassert_int_equal((rt_ubase_t)rt_smem_realloc(&heap->parent, ctx.ptr, ctx.size), (rt_ubase_t)ctx.ptr);
/* Get remaining size */
uassert_true(max_block(heap) > max_free);
/* Free memory */
uassert_int_equal(_mem_cmp(ctx.ptr, ctx.magic, ctx.size), 0);
rt_smem_free(ctx.ptr);
/* Check memory integrity */
uassert_int_equal(max_block(heap), total_size);
}
/* mem realloc test,equal */
{
rt_size_t max_free;
struct mem_test_context ctx;
/* alloc a piece of memory */
ctx.magic = magic++;
ctx.size = max_block(heap) / 2;
ctx.ptr = rt_smem_alloc(&heap->parent, ctx.size);
uassert_not_null(ctx.ptr);
rt_memset(ctx.ptr, ctx.magic, ctx.size);
uassert_int_equal(_mem_cmp(ctx.ptr, ctx.magic, ctx.size), 0);
/* Get remaining memory */
max_free = max_block(heap);
/* Do not change memory size */
uassert_int_equal((rt_ubase_t)rt_smem_realloc(&heap->parent, ctx.ptr, ctx.size), (rt_ubase_t)ctx.ptr);
/* Get remaining size */
uassert_true(max_block(heap) == max_free);
/* Free memory */
uassert_int_equal(_mem_cmp(ctx.ptr, ctx.magic, ctx.size), 0);
rt_smem_free(ctx.ptr);
/* Check memory integrity */
uassert_int_equal(max_block(heap), total_size);
}
/* small heap deinit */
rt_smem_detach(&heap->parent);
/* release test resources */
rt_free(buf);
}
struct mem_alloc_context
{
rt_list_t node;
rt_size_t size;
rt_uint8_t magic;
};
struct mem_alloc_head
{
rt_list_t list;
rt_size_t count;
rt_tick_t start;
rt_tick_t end;
rt_tick_t interval;
};
#define MEM_RANG_ALLOC_BLK_MIN 2
#define MEM_RANG_ALLOC_BLK_MAX 5
#define MEM_RANG_ALLOC_TEST_TIME 5
static void mem_alloc_test(void)
{
struct mem_alloc_head head;
rt_uint8_t *buf;
struct rt_small_mem *heap;
rt_size_t total_size, size;
struct mem_alloc_context *ctx;
/* init */
rt_list_init(&head.list);
head.count = 0;
head.start = rt_tick_get();
head.end = rt_tick_get() + rt_tick_from_millisecond(MEM_RANG_ALLOC_TEST_TIME * 1000);
head.interval = (head.end - head.start) / 20;
buf = rt_malloc(TEST_MEM_SIZE);
uassert_not_null(buf);
uassert_int_equal(RT_ALIGN((rt_ubase_t)buf, RT_ALIGN_SIZE), (rt_ubase_t)buf);
rt_memset(buf, 0xAA, TEST_MEM_SIZE);
heap = (struct rt_small_mem *)rt_smem_init("mem_tc", buf, TEST_MEM_SIZE);
total_size = max_block(heap);
uassert_int_not_equal(total_size, 0);
/* test run */
while (head.end - head.start < RT_TICK_MAX / 2)
{
if (rt_tick_get() - head.start >= head.interval)
{
head.start = rt_tick_get();
rt_kprintf("#");
}
/* %60 probability to perform alloc operation */
if (rand() % 10 >= 4)
{
size = rand() % MEM_RANG_ALLOC_BLK_MAX + MEM_RANG_ALLOC_BLK_MIN;
size *= sizeof(struct mem_alloc_context);
ctx = rt_smem_alloc(&heap->parent, size);
if (ctx == RT_NULL)
{
if (head.count == 0)
{
break;
}
size = head.count / 2;
while (size != head.count)
{
ctx = rt_list_first_entry(&head.list, struct mem_alloc_context, node);
rt_list_remove(&ctx->node);
if (ctx->size > sizeof(*ctx))
{
if (_mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)) != 0)
{
uassert_true(0);
}
}
rt_memset(ctx, 0xAA, ctx->size);
rt_smem_free(ctx);
head.count --;
}
continue;
}
if (RT_ALIGN((rt_ubase_t)ctx, RT_ALIGN_SIZE) != (rt_ubase_t)ctx)
{
uassert_int_equal(RT_ALIGN((rt_ubase_t)ctx, RT_ALIGN_SIZE), (rt_ubase_t)ctx);
}
rt_memset(ctx, 0, size);
rt_list_init(&ctx->node);
ctx->size = size;
ctx->magic = rand() & 0xff;
if (ctx->size > sizeof(*ctx))
{
rt_memset(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx));
}
rt_list_insert_after(&head.list, &ctx->node);
head.count += 1;
}
else
{
if (!rt_list_isempty(&head.list))
{
ctx = rt_list_first_entry(&head.list, struct mem_alloc_context, node);
rt_list_remove(&ctx->node);
if (ctx->size > sizeof(*ctx))
{
if (_mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)) != 0)
{
uassert_true(0);
}
}
rt_memset(ctx, 0xAA, ctx->size);
rt_smem_free(ctx);
head.count --;
}
}
}
while (!rt_list_isempty(&head.list))
{
ctx = rt_list_first_entry(&head.list, struct mem_alloc_context, node);
rt_list_remove(&ctx->node);
if (ctx->size > sizeof(*ctx))
{
if (_mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)) != 0)
{
uassert_true(0);
}
}
rt_memset(ctx, 0xAA, ctx->size);
rt_smem_free(ctx);
head.count --;
}
uassert_int_equal(head.count, 0);
uassert_int_equal(max_block(heap), total_size);
/* small heap deinit */
rt_smem_detach(&heap->parent);
/* release test resources */
rt_free(buf);
}
#define MEM_RANG_REALLOC_BLK_MIN 0
#define MEM_RANG_REALLOC_BLK_MAX 5
#define MEM_RANG_REALLOC_TEST_TIME 5
struct mem_realloc_context
{
rt_size_t size;
rt_uint8_t magic;
};
struct mem_realloc_head
{
struct mem_realloc_context **ctx_tab;
rt_size_t count;
rt_tick_t start;
rt_tick_t end;
rt_tick_t interval;
};
static void mem_realloc_test(void)
{
struct mem_realloc_head head;
rt_uint8_t *buf;
struct rt_small_mem *heap;
rt_size_t total_size, size, idx;
struct mem_realloc_context *ctx;
int res;
size = RT_ALIGN(sizeof(struct mem_realloc_context), RT_ALIGN_SIZE) + RT_ALIGN_SIZE;
size = TEST_MEM_SIZE / size;
/* init */
head.ctx_tab = RT_NULL;
head.count = size;
head.start = rt_tick_get();
head.end = rt_tick_get() + rt_tick_from_millisecond(MEM_RANG_ALLOC_TEST_TIME * 1000);
head.interval = (head.end - head.start) / 20;
buf = rt_malloc(TEST_MEM_SIZE);
uassert_not_null(buf);
uassert_int_equal(RT_ALIGN((rt_ubase_t)buf, RT_ALIGN_SIZE), (rt_ubase_t)buf);
rt_memset(buf, 0xAA, TEST_MEM_SIZE);
heap = (struct rt_small_mem *)rt_smem_init("mem_tc", buf, TEST_MEM_SIZE);
total_size = max_block(heap);
uassert_int_not_equal(total_size, 0);
/* init ctx tab */
size = head.count * sizeof(struct mem_realloc_context *);
head.ctx_tab = rt_smem_alloc(&heap->parent, size);
uassert_not_null(head.ctx_tab);
rt_memset(head.ctx_tab, 0, size);
/* test run */
while (head.end - head.start < RT_TICK_MAX / 2)
{
if (rt_tick_get() - head.start >= head.interval)
{
head.start = rt_tick_get();
rt_kprintf("#");
}
size = rand() % MEM_RANG_ALLOC_BLK_MAX + MEM_RANG_ALLOC_BLK_MIN;
size *= sizeof(struct mem_realloc_context);
idx = rand() % head.count;
ctx = rt_smem_realloc(&heap->parent, head.ctx_tab[idx], size);
if (ctx == RT_NULL)
{
if (size == 0)
{
if (head.ctx_tab[idx])
{
head.ctx_tab[idx] = RT_NULL;
}
}
else
{
for (idx = 0; idx < head.count; idx++)
{
ctx = head.ctx_tab[idx];
if (rand() % 2 && ctx)
{
if (ctx->size > sizeof(*ctx))
{
res = _mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx));
if (res != 0)
{
uassert_int_equal(res, 0);
}
}
rt_memset(ctx, 0xAA, ctx->size);
rt_smem_realloc(&heap->parent, ctx, 0);
head.ctx_tab[idx] = RT_NULL;
}
}
}
continue;
}
/* check mem */
if (head.ctx_tab[idx] != RT_NULL)
{
res = 0;
if (ctx->size < size)
{
if (ctx->size > sizeof(*ctx))
{
res = _mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx));
}
}
else
{
if (size > sizeof(*ctx))
{
res = _mem_cmp(&ctx[1], ctx->magic, size - sizeof(*ctx));
}
}
if (res != 0)
{
uassert_int_equal(res, 0);
}
}
/* init mem */
ctx->magic = rand() & 0xff;
ctx->size = size;
if (ctx->size > sizeof(*ctx))
{
rt_memset(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx));
}
head.ctx_tab[idx] = ctx;
}
/* free all mem */
for (idx = 0; idx < head.count; idx++)
{
ctx = head.ctx_tab[idx];
if (ctx == RT_NULL)
{
continue;
}
if (ctx->size > sizeof(*ctx))
{
res = _mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx));
if (res != 0)
{
uassert_int_equal(res, 0);
}
}
rt_memset(ctx, 0xAA, ctx->size);
rt_smem_realloc(&heap->parent, ctx, 0);
head.ctx_tab[idx] = RT_NULL;
}
uassert_int_not_equal(max_block(heap), total_size);
/* small heap deinit */
rt_smem_detach(&heap->parent);
/* release test resources */
rt_free(buf);
}
static rt_err_t utest_tc_init(void)
{
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
return RT_EOK;
}
static void testcase(void)
{
UTEST_UNIT_RUN(mem_functional_test);
UTEST_UNIT_RUN(mem_alloc_test);
UTEST_UNIT_RUN(mem_realloc_test);
}
UTEST_TC_EXPORT(testcase, "testcases.kernel.mem_tc", utest_tc_init, utest_tc_cleanup, 20);

View file

@ -0,0 +1,97 @@
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-01-16 flybreak the first version
*/
#include <rtthread.h>
#include <stdlib.h>
#include "utest.h"
#define HEAP_SIZE (64 * 1024)
#define HEAP_ALIGN (4)
#define SLICE_NUM (40)
#define TEST_TIMES (100000)
#define HEAP_NAME "heap1"
#define SLICE_SIZE_MAX (HEAP_SIZE/SLICE_NUM)
static void memheap_test(void)
{
struct rt_memheap heap1;
void * ptr_start;
void *ptr[SLICE_NUM];
int i, cnt = 0;
/* init heap */
ptr_start = rt_malloc_align(HEAP_SIZE, HEAP_ALIGN);
if (ptr_start == RT_NULL)
{
rt_kprintf("totle size too big,can not malloc memory!");
return;
}
rt_memheap_init(&heap1, HEAP_NAME, ptr_start, HEAP_SIZE);
/* test start */
for (i = 0; i < SLICE_NUM; i++)
{
ptr[i] = 0;
}
/* test alloc */
for (i = 0; i < SLICE_NUM; i++)
{
rt_uint32_t slice_size = rand() % SLICE_SIZE_MAX;
ptr[i] = rt_memheap_alloc(&heap1, slice_size);
}
/* test realloc */
while (cnt < TEST_TIMES)
{
rt_uint32_t slice_size = rand() % SLICE_SIZE_MAX;
rt_uint32_t ptr_index = rand() % SLICE_NUM;
rt_uint32_t operation = rand() % 2;
if (ptr[ptr_index])
{
if (operation == 0) /* free and malloc */
{
rt_memheap_free(ptr[ptr_index]);
ptr[ptr_index] = rt_memheap_alloc(&heap1, slice_size);
}
else /* realloc */
{
ptr[ptr_index] = rt_memheap_realloc(&heap1, ptr[ptr_index], slice_size);
}
}
cnt ++;
if (cnt % (TEST_TIMES / 10) == 0)
{
rt_kprintf(">");
}
}
rt_kprintf("test OK!\n");
/* test end */
rt_memheap_detach(&heap1);
rt_free_align((void *)ptr_start);
}
static rt_err_t utest_tc_init(void)
{
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
return RT_EOK;
}
static void testcase(void)
{
UTEST_UNIT_RUN(memheap_test);
}
UTEST_TC_EXPORT(testcase, "testcases.kernel.memheap_tc", utest_tc_init, utest_tc_cleanup, 10);

View file

@ -0,0 +1,192 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-08-28 Sherman the first version
*/
#include <rtthread.h>
#include "utest.h"
#define MSG_SIZE 4
#define MAX_MSGS 5
static struct rt_messagequeue static_mq;
static rt_uint8_t mq_buf[(MSG_SIZE + (rt_uint8_t)sizeof(rt_ubase_t)) * MAX_MSGS];
static struct rt_thread mq_send_thread;
static struct rt_thread mq_recv_thread;
static rt_uint8_t mq_send_stack[1024];
static rt_uint8_t mq_recv_stack[1024];
static struct rt_event finish_e;
#define MQSEND_FINISH 0x01
#define MQRECV_FINIHS 0x02
#ifdef RT_USING_HEAP
static rt_mq_t dynamic_mq;
#endif /* RT_USING_HEAP */
static void test_mq_init(void)
{
rt_err_t ret;
ret = rt_mq_init(&static_mq,"testmq1", mq_buf, MSG_SIZE, sizeof(mq_buf), RT_IPC_FLAG_FIFO);
uassert_true(ret == RT_EOK);
}
static void test_mq_create(void)
{
#ifdef RT_USING_HEAP
dynamic_mq = rt_mq_create("testmq2", MSG_SIZE, MAX_MSGS, RT_IPC_FLAG_FIFO);
uassert_true(dynamic_mq != RT_NULL);
#endif /* RT_USING_HEAP */
}
static void mq_send_case(rt_mq_t testmq)
{
rt_uint32_t send_buf[MAX_MSGS+1] = {0};
rt_err_t ret = RT_EOK;
for (int var = 0; var < MAX_MSGS; ++var)
{
send_buf[var] = var + 1;
ret = rt_mq_send_wait(testmq, &send_buf[var], sizeof(send_buf[0]), RT_WAITING_FOREVER);
uassert_true(ret == RT_EOK);
}
send_buf[MAX_MSGS] = MAX_MSGS + 1;
ret = rt_mq_send(testmq, &send_buf[MAX_MSGS], sizeof(send_buf[0]));
uassert_true(ret == -RT_EFULL);
ret = rt_mq_send_wait(testmq, &send_buf[MAX_MSGS], sizeof(send_buf[0]), RT_WAITING_FOREVER);
uassert_true(ret == RT_EOK);
while (testmq->entry != 0)
{
rt_thread_delay(100);
}
ret = rt_mq_send(testmq, &send_buf[1], sizeof(send_buf[0]));
uassert_true(ret == RT_EOK);
ret = rt_mq_send(testmq, &send_buf[2], sizeof(send_buf[0]));
uassert_true(ret == RT_EOK);
ret = rt_mq_urgent(testmq, &send_buf[0], sizeof(send_buf[0]));
uassert_true(ret == RT_EOK);
while (testmq->entry != 0)
{
rt_thread_delay(100);
}
ret = rt_mq_send(testmq, &send_buf[1], sizeof(send_buf[0]));
uassert_true(ret == RT_EOK);
ret = rt_mq_control(testmq, RT_IPC_CMD_RESET, RT_NULL);
uassert_true(ret == RT_EOK);
uassert_true(testmq->entry == 0);
}
static void mq_send_entry(void *param)
{
mq_send_case(&static_mq);
#ifdef RT_USING_HEAP
if(dynamic_mq != RT_NULL)
{
mq_send_case(dynamic_mq);
}
#endif /* RT_USING_HEAP */
rt_event_send(&finish_e, MQSEND_FINISH);
}
static void mq_recv_case(rt_mq_t testmq)
{
rt_uint32_t recv_buf[MAX_MSGS+1] = {0};
rt_err_t ret = RT_EOK;
for (int var = 0; var < MAX_MSGS + 1; ++var)
{
ret = rt_mq_recv(testmq, &recv_buf[var], sizeof(recv_buf[0]), RT_WAITING_FOREVER);
uassert_true(ret == RT_EOK);
uassert_true(recv_buf[var] == (var + 1));
}
for (int var = 0; var < 3; ++var)
{
ret = rt_mq_recv(testmq, &recv_buf[var], sizeof(recv_buf[0]), RT_WAITING_FOREVER);
uassert_true(ret == RT_EOK);
uassert_true(recv_buf[var] == (var + 1));
}
}
static void mq_recv_entry(void *param)
{
mq_recv_case(&static_mq);
#ifdef RT_USING_HEAP
if(dynamic_mq != RT_NULL)
{
mq_recv_case(dynamic_mq);
}
#endif /* RT_USING_HEAP */
rt_event_send(&finish_e, MQRECV_FINIHS);
}
static void test_mq_testcase(void)
{
rt_thread_startup(&mq_send_thread);
rt_thread_startup(&mq_recv_thread);
rt_event_recv(&finish_e, MQSEND_FINISH | MQRECV_FINIHS, RT_EVENT_FLAG_AND, RT_WAITING_FOREVER, RT_NULL);
}
static void test_mq_detach(void)
{
rt_err_t ret = rt_mq_detach(&static_mq);
uassert_true(ret == RT_EOK);
}
static void test_mq_delete(void)
{
#ifdef RT_USING_HEAP
rt_err_t ret = rt_mq_delete(dynamic_mq);
uassert_true(ret == RT_EOK);
#endif /* RT_USING_HEAP */
}
static rt_err_t utest_tc_init(void)
{
rt_err_t ret ;
ret = rt_thread_init(&mq_send_thread, "mq_send", mq_send_entry, RT_NULL, mq_send_stack, sizeof(mq_send_stack), 22, 20);
if(ret != RT_EOK)
return -RT_ERROR;
ret = rt_thread_init(&mq_recv_thread, "mq_recv", mq_recv_entry, RT_NULL, mq_recv_stack, sizeof(mq_recv_stack), 23, 20);
if(ret != RT_EOK)
return -RT_ERROR;
ret = rt_event_init(&finish_e, "finish", RT_IPC_FLAG_FIFO);
if(ret != RT_EOK)
return -RT_ERROR;
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
return RT_EOK;
}
static void testcase(void)
{
UTEST_UNIT_RUN(test_mq_init);
UTEST_UNIT_RUN(test_mq_create);
UTEST_UNIT_RUN(test_mq_testcase);
UTEST_UNIT_RUN(test_mq_detach);
UTEST_UNIT_RUN(test_mq_delete);
}
UTEST_TC_EXPORT(testcase, "testcases.kernel.messagequeue_tc", utest_tc_init, utest_tc_cleanup, 1000);

View file

@ -0,0 +1,676 @@
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-09.01 luckyzjq the first version
*/
#include <rtthread.h>
#include <stdlib.h>
#include "utest.h"
static struct rt_mutex static_mutex;
#ifdef RT_USING_HEAP
static rt_mutex_t dynamic_mutex;
#endif /* RT_USING_HEAP */
/* init test */
static void test_static_mutex_init(void)
{
rt_err_t result = -RT_ERROR;
result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
result = rt_mutex_detach(&static_mutex);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
result = rt_mutex_detach(&static_mutex);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
uassert_true(RT_TRUE);
}
/* static take test */
static void static_mutex_take_entry(void *param)
{
rt_err_t result;
rt_mutex_t mutex;
int rand_num = rand() % 0x1000;
mutex = (rt_mutex_t)param;
result = rt_mutex_take(mutex, rand_num);
if (RT_EOK == result)
{
uassert_true(RT_FALSE);
}
}
static void test_static_mutex_take(void)
{
rt_err_t result;
result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
return;
}
/* take mutex and not release */
result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
if (RT_EOK != result)
uassert_true(RT_FALSE);
rt_thread_t tid = rt_thread_create("mutex_th",
static_mutex_take_entry,
&static_mutex,
2048,
10,
10);
if (RT_NULL == tid)
{
uassert_true(RT_FALSE);
return;
}
/* startup thread take second */
rt_thread_startup(tid);
/* let system schedule */
rt_thread_mdelay(5);
result = rt_mutex_detach(&static_mutex);
if (RT_EOK != result)
uassert_true(RT_FALSE);
uassert_true(RT_TRUE);
}
/* static release test */
static void static_mutex_release_entry(void *param)
{
rt_err_t result;
rt_mutex_t mutex;
int rand_num = rand() % 0x1000;
mutex = (rt_mutex_t)param;
result = rt_mutex_take(mutex, rand_num);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
}
static void test_static_mutex_release(void)
{
rt_err_t result;
result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
return;
}
/* take mutex */
result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
if (RT_EOK != result)
uassert_true(RT_FALSE);
/* release mutex */
result = rt_mutex_release(&static_mutex);
if (RT_EOK != result)
uassert_true(RT_FALSE);
rt_thread_t tid = rt_thread_create("mutex_th",
static_mutex_release_entry,
&static_mutex,
2048,
10,
10);
if (RT_NULL == tid)
{
uassert_true(RT_FALSE);
return;
}
/* startup thread and take mutex second */
rt_thread_startup(tid);
/* let system schedule */
rt_thread_mdelay(5);
result = rt_mutex_detach(&static_mutex);
if (RT_EOK != result)
uassert_true(RT_FALSE);
uassert_true(RT_TRUE);
}
/* static trytake test */
static void static_mutex_trytake_entry(void *param)
{
rt_err_t result;
rt_mutex_t mutex;
mutex = (rt_mutex_t)param;
result = rt_mutex_trytake(mutex);
if (RT_EOK == result)
{
uassert_true(RT_FALSE);
}
}
static void test_static_mutex_trytake(void)
{
rt_err_t result;
result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
return;
}
/* take mutex and not release */
result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
if (RT_EOK != result)
uassert_true(RT_FALSE);
rt_thread_t tid = rt_thread_create("mutex_th",
static_mutex_trytake_entry,
&static_mutex,
2048,
10,
10);
if (RT_NULL == tid)
{
uassert_true(RT_FALSE);
return;
}
/* startup thread and trytake mutex second */
rt_thread_startup(tid);
/* let system schedule */
rt_thread_mdelay(5);
result = rt_mutex_detach(&static_mutex);
if (RT_EOK != result)
uassert_true(RT_FALSE);
uassert_true(RT_TRUE);
}
static rt_thread_t tid1 = RT_NULL;
static rt_thread_t tid2 = RT_NULL;
static rt_thread_t tid3 = RT_NULL;
/* static mutex priority reverse test */
static void static_thread1_entry(void *param)
{
/* let system schedule */
rt_thread_mdelay(100);
/* thread3 hode mutex thread2 take mutex */
/* check thread2 and thread3 priority */
if (tid2->current_priority != tid3->current_priority)
{
uassert_true(RT_FALSE);
}
else
{
uassert_true(RT_TRUE);
}
}
static void static_thread2_entry(void *param)
{
rt_err_t result;
rt_mutex_t mutex = (rt_mutex_t)param;
/* let system schedule */
rt_thread_mdelay(50);
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
if (result == RT_EOK)
{
rt_mutex_release(mutex);
}
}
static void static_thread3_entry(void *param)
{
rt_tick_t tick;
rt_err_t result;
rt_mutex_t mutex = (rt_mutex_t)param;
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
uassert_true(RT_FALSE);
}
tick = rt_tick_get();
while (rt_tick_get() - tick < (RT_TICK_PER_SECOND / 2));
rt_mutex_release(mutex);
}
static void test_static_pri_reverse(void)
{
rt_err_t result;
tid1 = RT_NULL;
tid2 = RT_NULL;
tid3 = RT_NULL;
result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
return;
}
/* thread1 */
tid1 = rt_thread_create("thread1",
static_thread1_entry,
&static_mutex,
1024,
10 - 1,
10);
if (tid1 != RT_NULL)
rt_thread_startup(tid1);
/* thread2 */
tid2 = rt_thread_create("thread2",
static_thread2_entry,
&static_mutex,
1024,
10,
10);
if (tid2 != RT_NULL)
rt_thread_startup(tid2);
/* thread3 */
tid3 = rt_thread_create("thread3",
static_thread3_entry,
&static_mutex,
1024,
10 + 1,
10);
if (tid3 != RT_NULL)
rt_thread_startup(tid3);
rt_thread_mdelay(1000);
result = rt_mutex_detach(&static_mutex);
if (RT_EOK != result)
uassert_true(RT_FALSE);
uassert_true(RT_TRUE);
}
/* create test */
static void test_dynamic_mutex_create(void)
{
rt_err_t result = -RT_ERROR;
/* PRIO mode */
dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
if (RT_NULL == dynamic_mutex)
{
uassert_true(RT_FALSE);
}
result = rt_mutex_delete(dynamic_mutex);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
/* FIFO mode */
dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
if (RT_NULL == dynamic_mutex)
{
uassert_true(RT_FALSE);
}
result = rt_mutex_delete(dynamic_mutex);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
uassert_true(RT_TRUE);
}
/* dynamic take test */
static void dynamic_mutex_take_entry(void *param)
{
rt_err_t result;
rt_mutex_t mutex;
int rand_num = rand() % 0x1000;
mutex = (rt_mutex_t)param;
result = rt_mutex_take(mutex, rand_num);
if (RT_EOK == result)
{
uassert_true(RT_FALSE);
}
}
static void test_dynamic_mutex_take(void)
{
rt_err_t result;
dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
if (RT_NULL == dynamic_mutex)
{
uassert_true(RT_FALSE);
return;
}
/* take mutex and not release */
result = rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
if (RT_EOK != result)
uassert_true(RT_FALSE);
rt_thread_t tid = rt_thread_create("mutex_th",
dynamic_mutex_take_entry,
dynamic_mutex,
2048,
10,
10);
if (RT_NULL == tid)
{
uassert_true(RT_FALSE);
return;
}
/* startup thread take second */
rt_thread_startup(tid);
/* let system schedule */
rt_thread_mdelay(5);
result = rt_mutex_delete(dynamic_mutex);
if (RT_EOK != result)
uassert_true(RT_FALSE);
uassert_true(RT_TRUE);
}
/* dynamic release test */
static void dynamic_mutex_release_entry(void *param)
{
rt_err_t result;
rt_mutex_t mutex;
int rand_num = rand() % 0x1000;
mutex = (rt_mutex_t)param;
result = rt_mutex_take(mutex, rand_num);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
}
static void test_dynamic_mutex_release(void)
{
rt_err_t result;
dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
if (RT_NULL == dynamic_mutex)
{
uassert_true(RT_FALSE);
return;
}
/* take mutex */
result = rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
if (RT_EOK != result)
uassert_true(RT_FALSE);
/* release mutex */
result = rt_mutex_release(dynamic_mutex);
if (RT_EOK != result)
uassert_true(RT_FALSE);
rt_thread_t tid = rt_thread_create("mutex_th",
dynamic_mutex_release_entry,
dynamic_mutex,
2048,
10,
10);
if (RT_NULL == tid)
{
uassert_true(RT_FALSE);
return;
}
/* startup thread and take mutex second */
rt_thread_startup(tid);
/* let system schedule */
rt_thread_mdelay(5);
result = rt_mutex_delete(dynamic_mutex);
if (RT_EOK != result)
uassert_true(RT_FALSE);
uassert_true(RT_TRUE);
}
/* dynamic trytake test */
static void dynamic_mutex_trytake_entry(void *param)
{
rt_err_t result;
rt_mutex_t mutex;
mutex = (rt_mutex_t)param;
result = rt_mutex_trytake(mutex);
if (RT_EOK == result)
{
uassert_true(RT_FALSE);
}
}
static void test_dynamic_mutex_trytake(void)
{
rt_err_t result;
dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
if (RT_NULL == dynamic_mutex)
{
uassert_true(RT_FALSE);
return;
}
/* take mutex and not release */
result = rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
if (RT_EOK != result)
uassert_true(RT_FALSE);
rt_thread_t tid = rt_thread_create("mutex_th",
dynamic_mutex_trytake_entry,
dynamic_mutex,
2048,
10,
10);
if (RT_NULL == tid)
{
uassert_true(RT_FALSE);
return;
}
/* startup thread and trytake mutex second */
rt_thread_startup(tid);
/* let system schedule */
rt_thread_mdelay(5);
result = rt_mutex_delete(dynamic_mutex);
if (RT_EOK != result)
uassert_true(RT_FALSE);
uassert_true(RT_TRUE);
}
/* dynamic mutex priority reverse test */
static void dynamic_thread1_entry(void *param)
{
/* let system schedule */
rt_thread_mdelay(100);
/* thread3 hode mutex thread2 take mutex */
/* check thread2 and thread3 priority */
if (tid2->current_priority != tid3->current_priority)
{
uassert_true(RT_FALSE);
}
else
{
uassert_true(RT_TRUE);
}
}
static void dynamic_thread2_entry(void *param)
{
rt_err_t result;
rt_mutex_t mutex = (rt_mutex_t)param;
/* let system schedule */
rt_thread_mdelay(50);
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
if (result == RT_EOK)
{
rt_mutex_release(mutex);
}
}
static void dynamic_thread3_entry(void *param)
{
rt_tick_t tick;
rt_err_t result;
rt_mutex_t mutex = (rt_mutex_t)param;
result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
uassert_true(RT_FALSE);
}
tick = rt_tick_get();
while (rt_tick_get() - tick < (RT_TICK_PER_SECOND / 2));
rt_mutex_release(mutex);
}
static void test_dynamic_pri_reverse(void)
{
rt_err_t result;
tid1 = RT_NULL;
tid2 = RT_NULL;
tid3 = RT_NULL;
dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
if (RT_NULL == dynamic_mutex)
{
uassert_true(RT_FALSE);
return;
}
/* thread1 */
tid1 = rt_thread_create("thread1",
dynamic_thread1_entry,
dynamic_mutex,
1024,
10 - 1,
10);
if (tid1 != RT_NULL)
rt_thread_startup(tid1);
/* thread2 */
tid2 = rt_thread_create("thread2",
dynamic_thread2_entry,
dynamic_mutex,
1024,
10,
10);
if (tid2 != RT_NULL)
rt_thread_startup(tid2);
/* thread3 */
tid3 = rt_thread_create("thread3",
dynamic_thread3_entry,
dynamic_mutex,
1024,
10 + 1,
10);
if (tid3 != RT_NULL)
rt_thread_startup(tid3);
rt_thread_mdelay(1000);
result = rt_mutex_delete(dynamic_mutex);
if (RT_EOK != result)
uassert_true(RT_FALSE);
uassert_true(RT_TRUE);
}
static rt_err_t utest_tc_init(void)
{
#ifdef RT_USING_HEAP
dynamic_mutex = RT_NULL;
#endif /* RT_USING_HEAP */
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
#ifdef RT_USING_HEAP
dynamic_mutex = RT_NULL;
#endif /* RT_USING_HEAP */
return RT_EOK;
}
static void testcase(void)
{
UTEST_UNIT_RUN(test_static_mutex_init);
UTEST_UNIT_RUN(test_static_mutex_take);
UTEST_UNIT_RUN(test_static_mutex_release);
UTEST_UNIT_RUN(test_static_mutex_trytake);
UTEST_UNIT_RUN(test_static_pri_reverse);
#ifdef RT_USING_HEAP
UTEST_UNIT_RUN(test_dynamic_mutex_create);
UTEST_UNIT_RUN(test_dynamic_mutex_take);
UTEST_UNIT_RUN(test_dynamic_mutex_release);
UTEST_UNIT_RUN(test_dynamic_mutex_trytake);
UTEST_UNIT_RUN(test_dynamic_pri_reverse);
#endif
}
UTEST_TC_EXPORT(testcase, "testcases.kernel.mutex_tc", utest_tc_init, utest_tc_cleanup, 1000);
/********************* end of file ************************/

View file

@ -0,0 +1,558 @@
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-08-12 luckyzjq the first version
*/
#include <rtthread.h>
#include <stdlib.h>
#include "utest.h"
static struct rt_semaphore static_semaphore;
#ifdef RT_USING_HEAP
static rt_sem_t dynamic_semaphore;
#endif /* RT_USING_HEAP */
static void test_static_semaphore_init(void)
{
rt_err_t result;
int rand_num = rand() % 0x10000;
for (int i = 0; i < rand_num; i++)
{
result = rt_sem_init(&static_semaphore, "static_sem", i, RT_IPC_FLAG_PRIO);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
break;
}
rt_sem_detach(&static_semaphore);
result = rt_sem_init(&static_semaphore, "static_sem", i, RT_IPC_FLAG_FIFO);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
break;
}
rt_sem_detach(&static_semaphore);
}
uassert_true(RT_TRUE);
}
static void test_static_semaphore_detach(void)
{
rt_err_t result;
int rand_num = rand() % 0x10000;
for (int i = 0; i < rand_num; i++)
{
result = rt_sem_init(&static_semaphore, "static_sem", i, RT_IPC_FLAG_PRIO);
if (RT_EOK != result)
{
break;
}
result = rt_sem_detach(&static_semaphore);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
break;
}
result = rt_sem_init(&static_semaphore, "static_sem", i, RT_IPC_FLAG_FIFO);
if (RT_EOK != result)
{
break;
}
result = rt_sem_detach(&static_semaphore);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
break;
}
}
uassert_true(RT_TRUE);
}
static void test_static_semaphore_take(void)
{
rt_err_t result;
result = rt_sem_init(&static_semaphore, "static_sem", 1, RT_IPC_FLAG_PRIO);
if (RT_EOK == result)
{
/* first take */
result = rt_sem_take(&static_semaphore, RT_WAITING_FOREVER);
if (RT_EOK != result)
uassert_true(RT_FALSE);
/* second take */
result = rt_sem_take(&static_semaphore, 100);
if (-RT_ETIMEOUT != result)
uassert_true(RT_FALSE);
}
else
{
return;
}
rt_sem_detach(&static_semaphore);
uassert_true(RT_TRUE);
return;
}
static void test_static_semaphore_trytake(void)
{
rt_err_t result;
result = rt_sem_init(&static_semaphore, "static_sem", 1, RT_IPC_FLAG_PRIO);
if (RT_EOK == result)
{
/* first take */
result = rt_sem_trytake(&static_semaphore);
if (RT_EOK != result)
uassert_true(RT_FALSE);
/* second take */
result = rt_sem_trytake(&static_semaphore);
if (-RT_ETIMEOUT != result)
uassert_true(RT_FALSE);
}
else
{
return;
}
rt_sem_detach(&static_semaphore);
uassert_true(RT_TRUE);
return;
}
static void test_static_semaphore_release(void)
{
rt_err_t result;
result = rt_sem_init(&static_semaphore, "static_sem", 0, RT_IPC_FLAG_PRIO);
if (RT_EOK == result)
{
/* first take */
result = rt_sem_take(&static_semaphore, 100);
if (-RT_ETIMEOUT != result)
uassert_true(RT_FALSE);
/* release */
result = rt_sem_release(&static_semaphore);
if (RT_EOK != result)
uassert_true(RT_FALSE);
/* second take */
result = rt_sem_take(&static_semaphore, RT_WAITING_FOREVER);
if (RT_EOK != result)
uassert_true(RT_FALSE);
}
else
{
return;
}
rt_sem_detach(&static_semaphore);
uassert_true(RT_TRUE);
return;
}
static void test_static_semaphore_control(void)
{
rt_err_t result;
int value = 0;
value = rand() % 100;
result = rt_sem_init(&static_semaphore, "static_sem", 1, RT_IPC_FLAG_PRIO);
if (RT_EOK == result)
{
result = rt_sem_control(&static_semaphore, RT_IPC_CMD_RESET, &value);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
}
else
{
return;
}
for (int i = 0; i < value; i++)
{
result = rt_sem_take(&static_semaphore, 10);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
}
rt_sem_detach(&static_semaphore);
uassert_true(RT_TRUE);
}
static void static_release_isr_hardware_callback(void *param)
{
rt_err_t result;
result = rt_sem_release(&static_semaphore);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
}
static void static_release_isr_software_callback(void *param)
{
rt_err_t result;
result = rt_sem_release(&static_semaphore);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
}
static void test_static_semaphore_release_isr(void)
{
rt_err_t result;
rt_timer_t hardware_timer;
rt_timer_t software_timer;
/* create timer */
hardware_timer = rt_timer_create("release_isr",
static_release_isr_hardware_callback,
RT_NULL,
100,
RT_TIMER_FLAG_HARD_TIMER | RT_TIMER_FLAG_ONE_SHOT);
software_timer = rt_timer_create("release_isr",
static_release_isr_software_callback,
RT_NULL,
100,
RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT);
/* start tiemr */
if (hardware_timer)
rt_timer_start(hardware_timer);
if (software_timer)
rt_timer_start(software_timer);
result = rt_sem_init(&static_semaphore, "static_sem", 0, RT_IPC_FLAG_PRIO);
if (RT_EOK == result)
{
for (int i = 0; i < 2; i++)
{
result = rt_sem_take(&static_semaphore, 1000);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
}
}
else
{
return;
}
rt_sem_detach(&static_semaphore);
rt_timer_delete(hardware_timer);
rt_timer_delete(software_timer);
uassert_true(RT_TRUE);
}
#ifdef RT_USING_HEAP
static void test_dynamic_semaphore_create(void)
{
int rand_num = rand() % 0x10000;
for (int i = 0; i < rand_num; i++)
{
dynamic_semaphore = rt_sem_create("static_sem", i, RT_IPC_FLAG_PRIO);
if (RT_NULL == dynamic_semaphore)
{
uassert_true(RT_FALSE);
break;
}
rt_sem_delete(dynamic_semaphore);
dynamic_semaphore = rt_sem_create("static_sem", i, RT_IPC_FLAG_FIFO);
if (RT_NULL == dynamic_semaphore)
{
uassert_true(RT_FALSE);
break;
}
rt_sem_delete(dynamic_semaphore);
}
uassert_true(RT_TRUE);
}
static void test_dynamic_semaphore_delete(void)
{
rt_err_t result;
int rand_num = rand() % 0x10000;
for (int i = 0; i < rand_num; i++)
{
dynamic_semaphore = rt_sem_create("static_sem", i, RT_IPC_FLAG_PRIO);
if (RT_NULL == dynamic_semaphore)
{
break;
}
result = rt_sem_delete(dynamic_semaphore);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
break;
}
dynamic_semaphore = rt_sem_create("static_sem", i, RT_IPC_FLAG_FIFO);
if (RT_NULL == dynamic_semaphore)
{
break;
}
result = rt_sem_delete(dynamic_semaphore);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
break;
}
}
uassert_true(RT_TRUE);
}
static void test_dynamic_semaphore_take(void)
{
rt_err_t result;
dynamic_semaphore = rt_sem_create("static_sem", 1, RT_IPC_FLAG_PRIO);
if (RT_NULL != dynamic_semaphore)
{
/* first take */
result = rt_sem_take(dynamic_semaphore, RT_WAITING_FOREVER);
if (RT_EOK != result)
uassert_true(RT_FALSE);
/* second take */
result = rt_sem_take(dynamic_semaphore, 100);
if (-RT_ETIMEOUT != result)
uassert_true(RT_FALSE);
}
else
{
return;
}
rt_sem_delete(dynamic_semaphore);
uassert_true(RT_TRUE);
return;
}
static void test_dynamic_semaphore_trytake(void)
{
rt_err_t result;
dynamic_semaphore = rt_sem_create("static_sem", 1, RT_IPC_FLAG_PRIO);
if (RT_NULL != dynamic_semaphore)
{
/* first take */
result = rt_sem_trytake(dynamic_semaphore);
if (RT_EOK != result)
uassert_true(RT_FALSE);
/* second take */
result = rt_sem_trytake(dynamic_semaphore);
if (-RT_ETIMEOUT != result)
uassert_true(RT_FALSE);
}
else
{
return;
}
rt_sem_delete(dynamic_semaphore);
uassert_true(RT_TRUE);
return;
}
static void test_dynamic_semaphore_release(void)
{
rt_err_t result;
dynamic_semaphore = rt_sem_create("static_sem", 0, RT_IPC_FLAG_PRIO);
if (RT_NULL != dynamic_semaphore)
{
/* first take */
result = rt_sem_take(dynamic_semaphore, 100);
if (-RT_ETIMEOUT != result)
uassert_true(RT_FALSE);
/* release */
result = rt_sem_release(dynamic_semaphore);
if (RT_EOK != result)
uassert_true(RT_FALSE);
/* second take */
result = rt_sem_take(dynamic_semaphore, RT_WAITING_FOREVER);
if (RT_EOK != result)
uassert_true(RT_FALSE);
}
else
{
return;
}
rt_sem_delete(dynamic_semaphore);
uassert_true(RT_TRUE);
return;
}
static void test_dynamic_semaphore_control(void)
{
rt_err_t result;
int value = 0;
value = rand() % 100;
dynamic_semaphore = rt_sem_create("static_sem", 1, RT_IPC_FLAG_PRIO);
if (RT_NULL != dynamic_semaphore)
{
result = rt_sem_control(dynamic_semaphore, RT_IPC_CMD_RESET, &value);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
}
else
{
return;
}
for (int i = 0; i < value; i++)
{
result = rt_sem_take(dynamic_semaphore, 10);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
}
rt_sem_delete(dynamic_semaphore);
uassert_true(RT_TRUE);
}
static void dynamic_release_isr_hardware_callback(void *param)
{
rt_err_t result;
result = rt_sem_release(dynamic_semaphore);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
}
static void dynamic_release_isr_software_callback(void *param)
{
rt_err_t result;
result = rt_sem_release(dynamic_semaphore);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
}
static void test_dynamic_semaphore_release_isr(void)
{
rt_err_t result;
rt_timer_t hardware_timer;
rt_timer_t software_timer;
/* create timer */
hardware_timer = rt_timer_create("release_isr",
dynamic_release_isr_hardware_callback,
RT_NULL,
100,
RT_TIMER_FLAG_HARD_TIMER | RT_TIMER_FLAG_ONE_SHOT);
software_timer = rt_timer_create("release_isr",
dynamic_release_isr_software_callback,
RT_NULL,
100,
RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT);
/* start tiemr */
if (hardware_timer)
rt_timer_start(hardware_timer);
if (software_timer)
rt_timer_start(software_timer);
dynamic_semaphore = rt_sem_create("static_sem", 0, RT_IPC_FLAG_PRIO);
if (RT_NULL != dynamic_semaphore)
{
for (int i = 0; i < 2; i++)
{
result = rt_sem_take(dynamic_semaphore, 1000);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
}
}
else
{
return;
}
rt_sem_delete(dynamic_semaphore);
rt_timer_delete(hardware_timer);
rt_timer_delete(software_timer);
uassert_true(RT_TRUE);
}
#endif /* RT_USING_HEAP */
static rt_err_t utest_tc_init(void)
{
#ifdef RT_USING_HEAP
dynamic_semaphore = RT_NULL;
#endif /* RT_USING_HEAP */
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
#ifdef RT_USING_HEAP
dynamic_semaphore = RT_NULL;
#endif /* RT_USING_HEAP */
return RT_EOK;
}
static void testcase(void)
{
UTEST_UNIT_RUN(test_static_semaphore_init);
UTEST_UNIT_RUN(test_static_semaphore_take);
UTEST_UNIT_RUN(test_static_semaphore_release);
UTEST_UNIT_RUN(test_static_semaphore_detach);
UTEST_UNIT_RUN(test_static_semaphore_trytake);
UTEST_UNIT_RUN(test_static_semaphore_control);
UTEST_UNIT_RUN(test_static_semaphore_release_isr);
#ifdef RT_USING_HEAP
UTEST_UNIT_RUN(test_dynamic_semaphore_create);
UTEST_UNIT_RUN(test_dynamic_semaphore_take);
UTEST_UNIT_RUN(test_dynamic_semaphore_release);
UTEST_UNIT_RUN(test_dynamic_semaphore_delete);
UTEST_UNIT_RUN(test_dynamic_semaphore_trytake);
UTEST_UNIT_RUN(test_dynamic_semaphore_control);
UTEST_UNIT_RUN(test_dynamic_semaphore_release_isr);
#endif /* RT_USING_HEAP */
}
UTEST_TC_EXPORT(testcase, "testcases.kernel.semaphore_tc", utest_tc_init, utest_tc_cleanup, 1000);

View file

@ -0,0 +1,199 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-08-12 flybreak the first version
*
* case 1:rt_signal_install, install all available signal
* case 2:rt_signal_install, install illegal signal
* case 3:rt_signal_mask/unmask, one thread self, install and unmask, then kill, should received.
* case 4:rt_signal_mask/unmask, one thread self, install and unmask and mask, then kill, should can't received.
* case 5:rt_signal_wait, two thread, thread1: install and unmask, then wait 1s; thread2: kill, should received.
* case 6:rt_signal_wait, two thread, thread1: install and unmask, then wait 1s; thread2: sleep 2s then kill, should can't received.
* case 7:rt_signal_kill, kill legal thread, return 0;
* case 8:rt_signal_kill, kill illegal thread, return failed (unused);
* case 9:rt_signal_kill, kill illegal signo, return -RT_EINVAL;
*
*/
#include <rtthread.h>
#include "utest.h"
int recive_sig = 0;
void sig_handle_default(int signo)
{
recive_sig = signo;
}
static void rt_signal_install_test(void)
{
int signo;
rt_sighandler_t result;
/* case 1:rt_signal_install, install all available signal. */
for (signo = 0; signo < RT_SIG_MAX; signo++)
{
result = rt_signal_install(signo, sig_handle_default);
uassert_true(result != SIG_ERR);
}
/* case 2:rt_signal_install, install illegal signal. */
result = rt_signal_install(signo, sig_handle_default);
uassert_true(result == SIG_ERR);
return;
}
static void rt_signal_mask_test(void)
{
int signo;
rt_sighandler_t result;
/* case 3:rt_signal_mask/unmask, one thread self, install and unmask, then kill, should received. */
for (signo = 0; signo < RT_SIG_MAX; signo++)
{
recive_sig = -1;
result = rt_signal_install(signo, sig_handle_default);
uassert_true(result != SIG_ERR);
rt_signal_unmask(signo);
uassert_int_equal(rt_thread_kill(rt_thread_self(), signo), RT_EOK);
rt_thread_mdelay(1);
uassert_int_equal(recive_sig, signo);
}
return;
}
static void rt_signal_unmask_test(void)
{
int signo;
rt_sighandler_t result;
/* case 4:rt_signal_mask/unmask, one thread self, install and unmask and mask, then kill, should can't received. */
for (signo = 0; signo < RT_SIG_MAX; signo++)
{
recive_sig = -1;
result = rt_signal_install(signo, sig_handle_default);
uassert_true(result != SIG_ERR);
rt_signal_unmask(signo);
rt_signal_mask(signo);
uassert_int_equal(rt_thread_kill(rt_thread_self(), signo), RT_EOK);
rt_thread_mdelay(1);
uassert_int_not_equal(recive_sig, signo);
}
return;
}
static void rt_signal_kill_test(void)
{
int signo;
rt_sighandler_t result;
/* case 7:rt_signal_kill, kill legal thread, return 0; */
for (signo = 0; signo < RT_SIG_MAX; signo++)
{
recive_sig = -1;
result = rt_signal_install(signo, sig_handle_default);
uassert_true(result != SIG_ERR);
rt_signal_unmask(signo);
uassert_int_equal(rt_thread_kill(rt_thread_self(), signo), RT_EOK);
rt_thread_mdelay(1);
uassert_int_equal(recive_sig, signo);
}
/* case 8:rt_signal_kill, kill illegal thread, return failed; */
// uassert_true(rt_thread_kill((rt_thread_t)-1, signo) == -RT_ERROR);
/* case 9:rt_signal_kill, kill illegal signo, return -RT_EINVAL; */
uassert_true(rt_thread_kill(rt_thread_self(), -1) == -RT_EINVAL);
return;
}
void rt_signal_wait_thread(void *parm)
{
sigset_t selectset;
siginfo_t recive_si;
rt_signal_install(SIGUSR1, sig_handle_default);
rt_signal_unmask(SIGUSR1);
(void)sigemptyset(&selectset);
(void)sigaddset(&selectset, SIGUSR1);
/* case 5:rt_signal_wait, two thread, thread1: install and unmask, then wait 1s; thread2: kill, should received. */
if (rt_signal_wait(&selectset, &recive_si, RT_TICK_PER_SECOND) != RT_EOK)
{
return;
}
recive_sig = recive_si.si_signo;
}
static void rt_signal_wait_test(void)
{
rt_thread_t t1;
recive_sig = -1;
t1 = rt_thread_create("sig_t1", rt_signal_wait_thread, 0, 4096, 14, 10);
if (t1)
{
rt_thread_startup(t1);
}
rt_thread_mdelay(1);
/* case 5:rt_signal_wait, two thread, thread1: install and unmask, then wait 1s; thread2: kill, should received. */
uassert_int_equal(rt_thread_kill(t1, SIGUSR1), RT_EOK);
rt_thread_mdelay(1);
uassert_int_equal(recive_sig, SIGUSR1);
return;
}
static void rt_signal_wait_test2(void)
{
rt_thread_t t1;
recive_sig = -1;
t1 = rt_thread_create("sig_t1", rt_signal_wait_thread, 0, 4096, 14, 10);
if (t1)
{
rt_thread_startup(t1);
}
/* case 6:rt_signal_wait, two thread, thread1: install and unmask, then wait 1s; thread2: sleep 2s then kill, should can't received. */
rt_thread_mdelay(2000);
uassert_int_equal(rt_thread_kill(t1, SIGUSR1), RT_EOK);
rt_thread_mdelay(1);
uassert_int_not_equal(recive_sig, SIGUSR1);
return;
}
static rt_err_t utest_tc_init(void)
{
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
return RT_EOK;
}
static void testcase(void)
{
#ifdef RT_USING_HEAP
UTEST_UNIT_RUN(rt_signal_install_test);
UTEST_UNIT_RUN(rt_signal_mask_test);
UTEST_UNIT_RUN(rt_signal_unmask_test);
UTEST_UNIT_RUN(rt_signal_kill_test);
UTEST_UNIT_RUN(rt_signal_wait_test);
UTEST_UNIT_RUN(rt_signal_wait_test2);
#endif /* RT_USING_HEAP */
}
UTEST_TC_EXPORT(testcase, "testcases.kernel.signal_tc", utest_tc_init, utest_tc_cleanup, 1000);
/*********************** end of file ****************************/

View file

@ -0,0 +1,323 @@
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-10-14 tyx the first version
*/
#include <rtthread.h>
#include <stdlib.h>
#include "utest.h"
#define TEST_SLAB_SIZE 1024 * 1024
static int _mem_cmp(void *ptr, rt_uint8_t v, rt_size_t size)
{
while (size-- != 0)
{
if (*(rt_uint8_t *)ptr != v)
return *(rt_uint8_t *)ptr - v;
}
return 0;
}
struct slab_alloc_context
{
rt_list_t node;
rt_size_t size;
rt_uint8_t magic;
};
struct slab_alloc_head
{
rt_list_t list;
rt_size_t count;
rt_tick_t start;
rt_tick_t end;
rt_tick_t interval;
};
#define SLAB_RANG_ALLOC_BLK_MIN 2
#define SLAB_RANG_ALLOC_BLK_MAX 5
#define SLAB_RANG_ALLOC_TEST_TIME 5
static void slab_alloc_test(void)
{
struct slab_alloc_head head;
rt_uint8_t *buf;
rt_slab_t heap;
rt_size_t size;
struct slab_alloc_context *ctx;
/* init */
rt_list_init(&head.list);
head.count = 0;
head.start = rt_tick_get();
head.end = rt_tick_get() + rt_tick_from_millisecond(SLAB_RANG_ALLOC_TEST_TIME * 1000);
head.interval = (head.end - head.start) / 20;
buf = rt_malloc(TEST_SLAB_SIZE);
uassert_not_null(buf);
uassert_int_equal(RT_ALIGN((rt_ubase_t)buf, RT_ALIGN_SIZE), (rt_ubase_t)buf);
rt_memset(buf, 0xAA, TEST_SLAB_SIZE);
heap = rt_slab_init("slab_tc", buf, TEST_SLAB_SIZE);
// test run
while (head.end - head.start < RT_TICK_MAX / 2)
{
if (rt_tick_get() - head.start >= head.interval)
{
head.start = rt_tick_get();
rt_kprintf("#");
}
// %60 probability to perform alloc operation
if (rand() % 10 >= 4)
{
size = rand() % SLAB_RANG_ALLOC_BLK_MAX + SLAB_RANG_ALLOC_BLK_MIN;
size *= sizeof(struct slab_alloc_context);
ctx = rt_slab_alloc(heap, size);
if (ctx == RT_NULL)
{
if (head.count == 0)
{
break;
}
size = head.count / 2;
while (size != head.count)
{
ctx = rt_list_first_entry(&head.list, struct slab_alloc_context, node);
rt_list_remove(&ctx->node);
if (ctx->size > sizeof(*ctx))
{
if (_mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)) != 0)
{
uassert_true(0);
}
}
rt_memset(ctx, 0xAA, ctx->size);
rt_slab_free(heap, ctx);
head.count --;
}
continue;
}
//if (RT_ALIGN((rt_ubase_t)ctx, RT_ALIGN_SIZE) != (rt_ubase_t)ctx)
//{
// uassert_int_equal(RT_ALIGN((rt_ubase_t)ctx, RT_ALIGN_SIZE), (rt_ubase_t)ctx);
//}
rt_memset(ctx, 0, size);
rt_list_init(&ctx->node);
ctx->size = size;
ctx->magic = rand() & 0xff;
if (ctx->size > sizeof(*ctx))
{
rt_memset(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx));
}
rt_list_insert_after(&head.list, &ctx->node);
head.count += 1;
}
else
{
if (!rt_list_isempty(&head.list))
{
ctx = rt_list_first_entry(&head.list, struct slab_alloc_context, node);
rt_list_remove(&ctx->node);
if (ctx->size > sizeof(*ctx))
{
if (_mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)) != 0)
{
uassert_true(0);
}
}
rt_memset(ctx, 0xAA, ctx->size);
rt_slab_free(heap, ctx);
head.count --;
}
}
}
while (!rt_list_isempty(&head.list))
{
ctx = rt_list_first_entry(&head.list, struct slab_alloc_context, node);
rt_list_remove(&ctx->node);
if (ctx->size > sizeof(*ctx))
{
if (_mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx)) != 0)
{
uassert_true(0);
}
}
rt_memset(ctx, 0xAA, ctx->size);
rt_slab_free(heap, ctx);
head.count --;
}
uassert_int_equal(head.count, 0);
// slab heap deinit
rt_slab_detach(heap);
/* release test resources */
rt_free(buf);
}
#define SLAB_RANG_REALLOC_BLK_MIN 0
#define SLAB_RANG_REALLOC_BLK_MAX 5
#define SLAB_RANG_REALLOC_TEST_TIME 5
struct slab_realloc_context
{
rt_size_t size;
rt_uint8_t magic;
};
struct slab_realloc_head
{
struct slab_realloc_context **ctx_tab;
rt_size_t count;
rt_tick_t start;
rt_tick_t end;
rt_tick_t interval;
};
static void slab_realloc_test(void)
{
struct slab_realloc_head head;
rt_uint8_t *buf;
rt_slab_t heap;
rt_size_t size, idx;
struct slab_realloc_context *ctx;
int res;
size = RT_ALIGN(sizeof(struct slab_realloc_context), RT_ALIGN_SIZE) + RT_ALIGN_SIZE;
size = TEST_SLAB_SIZE / size;
/* init */
head.ctx_tab = RT_NULL;
head.count = size;
head.start = rt_tick_get();
head.end = rt_tick_get() + rt_tick_from_millisecond(SLAB_RANG_ALLOC_TEST_TIME * 1000);
head.interval = (head.end - head.start) / 20;
buf = rt_malloc(TEST_SLAB_SIZE);
uassert_not_null(buf);
uassert_int_equal(RT_ALIGN((rt_ubase_t)buf, RT_ALIGN_SIZE), (rt_ubase_t)buf);
rt_memset(buf, 0xAA, TEST_SLAB_SIZE);
heap = rt_slab_init("slab_tc", buf, TEST_SLAB_SIZE);
/* init ctx tab */
size = head.count * sizeof(struct slab_realloc_context *);
head.ctx_tab = rt_slab_alloc(heap, size);
uassert_not_null(head.ctx_tab);
rt_memset(head.ctx_tab, 0, size);
// test run
while (head.end - head.start < RT_TICK_MAX / 2)
{
if (rt_tick_get() - head.start >= head.interval)
{
head.start = rt_tick_get();
rt_kprintf("#");
}
size = rand() % SLAB_RANG_ALLOC_BLK_MAX + SLAB_RANG_ALLOC_BLK_MIN;
size *= sizeof(struct slab_realloc_context);
idx = rand() % head.count;
ctx = rt_slab_realloc(heap, head.ctx_tab[idx], size);
if (ctx == RT_NULL)
{
if (size == 0)
{
if (head.ctx_tab[idx])
{
head.ctx_tab[idx] = RT_NULL;
}
}
else
{
for (idx = 0; idx < head.count; idx++)
{
ctx = head.ctx_tab[idx];
if (rand() % 2 && ctx)
{
if (ctx->size > sizeof(*ctx))
{
res = _mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx));
if (res != 0)
{
uassert_int_equal(res, 0);
}
}
rt_memset(ctx, 0xAA, ctx->size);
rt_slab_realloc(heap, ctx, 0);
head.ctx_tab[idx] = RT_NULL;
}
}
}
continue;
}
/* check slab */
if (head.ctx_tab[idx] != RT_NULL)
{
res = 0;
if (ctx->size < size)
{
if (ctx->size > sizeof(*ctx))
{
res = _mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx));
}
}
else
{
if (size > sizeof(*ctx))
{
res = _mem_cmp(&ctx[1], ctx->magic, size - sizeof(*ctx));
}
}
if (res != 0)
{
uassert_int_equal(res, 0);
}
}
/* init slab */
ctx->magic = rand() & 0xff;
ctx->size = size;
if (ctx->size > sizeof(*ctx))
{
rt_memset(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx));
}
head.ctx_tab[idx] = ctx;
}
// free all slab
for (idx = 0; idx < head.count; idx++)
{
ctx = head.ctx_tab[idx];
if (ctx == RT_NULL)
{
continue;
}
if (ctx->size > sizeof(*ctx))
{
res = _mem_cmp(&ctx[1], ctx->magic, ctx->size - sizeof(*ctx));
if (res != 0)
{
uassert_int_equal(res, 0);
}
}
rt_memset(ctx, 0xAA, ctx->size);
rt_slab_realloc(heap, ctx, 0);
head.ctx_tab[idx] = RT_NULL;
}
// slab heap deinit
rt_slab_detach(heap);
/* release test resources */
rt_free(buf);
}
static rt_err_t utest_tc_init(void)
{
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
return RT_EOK;
}
static void testcase(void)
{
UTEST_UNIT_RUN(slab_alloc_test);
UTEST_UNIT_RUN(slab_realloc_test);
}
UTEST_TC_EXPORT(testcase, "testcases.kernel.slab_tc", utest_tc_init, utest_tc_cleanup, 20);

View file

@ -0,0 +1,743 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-09.01 yangjie the firet version
* 2021-10.11 mazhiyuan add idle, yield, suspend, control, priority, delay_until
*/
#include <rtthread.h>
#include <stdlib.h>
#include "utest.h"
#define THREAD_STACK_SIZE 512
#define THREAD_TIMESLICE 10
rt_align(RT_ALIGN_SIZE)
static char thread2_stack[1024];
static struct rt_thread thread2;
#ifdef RT_USING_HEAP
static rt_thread_t tid1 = RT_NULL;
static rt_thread_t tid3 = RT_NULL;
static rt_thread_t tid4 = RT_NULL;
static rt_thread_t tid5 = RT_NULL;
static rt_thread_t tid6 = RT_NULL;
static rt_thread_t tid7 = RT_NULL;
#endif /* RT_USING_HEAP */
static volatile rt_uint32_t tid3_delay_pass_flag = 0;
static volatile rt_uint32_t tid3_finish_flag = 0;
static volatile rt_uint32_t tid4_finish_flag = 0;
static volatile rt_uint32_t tid6_finish_flag = 0;
static rt_uint32_t thread5_source = 0;
#ifndef RT_USING_SMP
static rt_uint32_t thread_yield_flag = 0;
#endif
static rt_uint32_t entry_idle_hook_times = 0;
static rt_thread_t __current_thread;
static rt_uint8_t change_priority;
static rt_uint32_t count = 0;
void thread1_entry(void *param)
{
while (1);
}
static void test_dynamic_thread(void)
{
rt_err_t ret_startup = -RT_ERROR;
rt_err_t ret_delete = -RT_ERROR;
tid1 = rt_thread_create("thread1",
thread1_entry,
(void *)1,
THREAD_STACK_SIZE,
__current_thread->current_priority + 1,
THREAD_TIMESLICE - 5);
if (tid1 == RT_NULL)
{
uassert_false(tid1 == RT_NULL);
goto __exit;
}
ret_startup = rt_thread_startup(tid1);
if (ret_startup != RT_EOK)
{
uassert_false(ret_startup != RT_EOK);
goto __exit;
}
ret_delete = rt_thread_delete(tid1);
if (ret_delete != RT_EOK)
{
uassert_false(ret_delete != RT_EOK);
goto __exit;
}
uassert_true(tid1 != RT_NULL && ret_startup == RT_EOK && ret_delete == RT_EOK);
__exit:
if (tid1 != RT_NULL && ret_delete != RT_EOK)
{
rt_thread_delete(tid1);
}
return;
}
void thread2_entry(void *param)
{
while (1);
}
static void test_static_thread(void)
{
rt_err_t ret_init = -RT_ERROR;
rt_err_t ret_startup = -RT_ERROR;
rt_err_t ret_detach = -RT_ERROR;
ret_init = rt_thread_init(&thread2,
"thread2",
thread2_entry,
(void *)2,
&thread2_stack[0],
sizeof(thread2_stack),
__current_thread->current_priority + 1,
THREAD_TIMESLICE);
if (ret_init != RT_EOK)
{
uassert_false(ret_init != RT_EOK);
goto __exit;
}
ret_startup = rt_thread_startup(&thread2);
if (ret_startup != RT_EOK)
{
uassert_false(ret_startup != RT_EOK);
goto __exit;
}
ret_detach = rt_thread_detach(&thread2);
if (ret_detach != RT_EOK)
{
uassert_false(ret_detach != RT_EOK);
goto __exit;
}
uassert_true(ret_init == RT_EOK && ret_startup == RT_EOK && ret_detach == RT_EOK);
__exit:
if (ret_init == RT_EOK && ret_detach != RT_EOK)
{
rt_thread_detach(&thread2);
}
return;
}
static void thread3_entry(void *parameter)
{
rt_tick_t tick;
tick = rt_tick_get();
rt_thread_delay(15);
if (rt_tick_get() - tick > 16)
{
tid3_finish_flag = 1;
tid3_delay_pass_flag = 0;
return;
}
tid3_delay_pass_flag = 1;
tid3_finish_flag = 1;
}
static void test_thread_delay(void)
{
rt_err_t ret_startup = -RT_ERROR;
tid3 = rt_thread_create("thread3",
thread3_entry,
RT_NULL,
THREAD_STACK_SIZE,
__current_thread->current_priority - 1,
THREAD_TIMESLICE);
if (tid3 == RT_NULL)
{
LOG_E("rt_thread_create failed!");
uassert_false(tid3 == RT_NULL);
goto __exit;
}
ret_startup = rt_thread_startup(tid3);
if (ret_startup != RT_EOK)
{
LOG_E("rt_thread_startup failed!");
uassert_false(1);
goto __exit;
}
while (tid3_finish_flag != 1);
uassert_true(tid3_delay_pass_flag == 1);
__exit:
return;
}
static void idle_hook(void)
{
entry_idle_hook_times ++;
}
static void thread4_entry(void *parameter)
{
rt_uint32_t delay_times = 5;
while (delay_times --)
{
rt_thread_mdelay(300);
}
rt_thread_idle_delhook(idle_hook);
tid4_finish_flag = 1;
}
static void test_idle_hook(void)
{
rt_err_t ret_startup = -RT_ERROR;
rt_thread_idle_sethook(idle_hook);
tid4 = rt_thread_create("thread4",
thread4_entry,
RT_NULL,
THREAD_STACK_SIZE,
__current_thread->current_priority - 1,
THREAD_TIMESLICE);
if (tid4 == RT_NULL)
{
LOG_E("rt_thread_create failed!");
uassert_false(tid4 == RT_NULL);
goto __exit;
}
ret_startup = rt_thread_startup(tid4);
if (ret_startup != RT_EOK)
{
LOG_E("rt_thread_startup failed!");
uassert_false(1);
goto __exit;
}
while (tid4_finish_flag != 1)
{
rt_thread_mdelay(200);
}
uassert_true(entry_idle_hook_times > 0);
__exit:
return;
}
static void thread5_entry(void *parameter)
{
while (1)
{
thread5_source ++;
rt_thread_delay(5);
if (thread5_source == 5)
{
rt_thread_yield();
}
}
}
static void thread6_entry(void *parameter)
{
while (++ thread5_source <= 9);
tid6_finish_flag = 1;
}
static void test_thread_yield(void)
{
rt_err_t ret_startup = -RT_ERROR;
thread5_source = 0;
tid5 = rt_thread_create("thread5",
thread5_entry,
RT_NULL,
THREAD_STACK_SIZE,
__current_thread->current_priority - 1,
THREAD_TIMESLICE);
if (tid5 == RT_NULL)
{
LOG_E("rt_thread_create failed!");
uassert_false(tid5 == RT_NULL);
goto __exit;
}
ret_startup = rt_thread_startup(tid5);
if (ret_startup != RT_EOK)
{
LOG_E("rt_thread_startup failed!");
uassert_false(1);
goto __exit;
}
tid6 = rt_thread_create("thread6",
thread6_entry,
RT_NULL,
THREAD_STACK_SIZE,
__current_thread->current_priority - 1,
THREAD_TIMESLICE);
if (tid6 == RT_NULL)
{
LOG_E("rt_thread_create failed!");
uassert_false(tid6 == RT_NULL);
goto __exit;
}
ret_startup = rt_thread_startup(tid6);
if (ret_startup != RT_EOK)
{
LOG_E("rt_thread_startup failed!");
uassert_false(1);
goto __exit;
}
while (tid6_finish_flag != 1);
uassert_true(thread5_source == 10);
__exit:
if (tid5 != RT_NULL)
{
rt_thread_delete(tid5);
}
return;
}
static void thread7_entry(void *parameter)
{
while (1);
}
static void test_thread_control(void)
{
rt_err_t ret_control = -RT_ERROR;
rt_err_t rst_delete = -RT_ERROR;
tid7 = rt_thread_create("thread7",
thread7_entry,
RT_NULL,
THREAD_STACK_SIZE,
__current_thread->current_priority + 1,
THREAD_TIMESLICE);
if (tid7 == RT_NULL)
{
LOG_E("rt_thread_create failed!");
uassert_false(tid7 == RT_NULL);
goto __exit;
}
ret_control = rt_thread_control(tid7, RT_THREAD_CTRL_STARTUP, RT_NULL);
if (ret_control != RT_EOK)
{
LOG_E("rt_thread_control failed!");
uassert_false(1);
goto __exit;
}
rt_thread_mdelay(200);
rt_thread_control(tid7, RT_THREAD_CTRL_CHANGE_PRIORITY, &change_priority);
if (tid7->current_priority != change_priority)
{
LOG_E("rt_thread_control failed!");
uassert_false(1);
goto __exit;
}
rst_delete = rt_thread_control(tid7, RT_THREAD_CTRL_CLOSE, RT_NULL);
if (rst_delete != RT_EOK)
{
LOG_E("rt_thread_control failed!");
uassert_false(rst_delete != RT_EOK);
goto __exit;
}
uassert_true(1);
__exit:
if (tid7 != RT_NULL && rst_delete != RT_EOK)
{
rt_thread_delete(tid7);
}
return;
}
static void thread8_entry(void *parameter)
{
for (; count < 10; count ++);
}
static void test_thread_priority(void)
{
rt_err_t ret_startup = -RT_ERROR;
rt_thread_t tid8 = RT_NULL;
tid8 = rt_thread_create("thread8",
thread8_entry,
RT_NULL,
THREAD_STACK_SIZE,
__current_thread->current_priority - 1,
THREAD_TIMESLICE);
if (tid8 == RT_NULL)
{
LOG_E("rt_thread_create failed!");
uassert_false(tid8 == RT_NULL);
return;
}
count = 0;
ret_startup = rt_thread_startup(tid8);
if (ret_startup != RT_EOK)
{
uassert_false(ret_startup != RT_EOK);
return ;
}
uassert_true(count == 10);
return;
}
static void test_delay_until(void)
{
rt_tick_t tick;
rt_tick_t check_tick = 0;
rt_tick_t delta = 0;
tick = rt_tick_get();
check_tick = tick;
rt_thread_delay_until(&tick, 100);
delta = rt_tick_get() - check_tick;
rt_kprintf("delta[100] -> %d\n", delta);
uassert_int_equal(delta, 100);
check_tick = tick;
rt_thread_delay(2);
rt_thread_delay_until(&tick, 200);
delta = rt_tick_get() - check_tick;
rt_kprintf("delta[200] -> %d\n", delta);
uassert_int_equal(delta, 200);
check_tick = tick;
rt_thread_delay(2);
rt_thread_delay_until(&tick, 300);
delta = rt_tick_get() - check_tick;
rt_kprintf("delta[300] -> %d\n", delta);
uassert_int_equal(delta, 300);
check_tick = tick;
rt_thread_delay(2);
rt_thread_delay_until(&tick, 100);
delta = rt_tick_get() - check_tick;
uassert_int_equal(delta, 100);
check_tick = tick;
rt_thread_delay(2);
rt_thread_delay_until(&tick, 50);
delta = rt_tick_get() - check_tick;
rt_kprintf("delta[50] -> %d\n", delta);
uassert_int_equal(delta, 50);
check_tick = tick;
rt_thread_delay(2);
rt_thread_delay_until(&tick, 20);
delta = rt_tick_get() - check_tick;
rt_kprintf("delta[20] -> %d\n", delta);
uassert_int_equal(delta, 20);
check_tick = tick;
rt_thread_delay(2);
rt_thread_delay_until(&tick, 10);
delta = rt_tick_get() - check_tick;
rt_kprintf("delta[10] -> %d\n", delta);
uassert_int_equal(delta, 10);
}
static rt_thread_t tidA, tidB1, tidB2;
static uint32_t timeslice_cntA, timeslice_cntB1, timeslice_cntB2;
static void test_timeslice_threadA_entry(void *parameter)
{
while (1)
{
rt_thread_delay(2);
timeslice_cntA++;
if (timeslice_cntA > 10) return;
}
}
static void test_timeslice_threadB1_entry(void *parameter)
{
while (1)
{
timeslice_cntB1++;
if (timeslice_cntA > 10) return;
}
}
static void test_timeslice_threadB2_entry(void *parameter)
{
while (1)
{
timeslice_cntB2++;
if (timeslice_cntA > 10) return;
}
}
void test_timeslice(void)
{
rt_err_t ret_startup = -RT_ERROR;
uint32_t diff;
timeslice_cntA = 0;
timeslice_cntB1 = 0;
timeslice_cntB2 = 0;
tidA = rt_thread_create("timeslice", test_timeslice_threadA_entry, RT_NULL,
2048, __current_thread->current_priority + 1, 10);
if (!tidA)
{
LOG_E("rt_thread_create failed!");
return;
}
rt_thread_control(tidA, RT_THREAD_CTRL_BIND_CPU, (void *)1);
ret_startup = rt_thread_startup(tidA);
if (ret_startup != RT_EOK)
{
LOG_E("rt_thread_startup failed!");
uassert_false(1);
return ;
}
tidB1 = rt_thread_create("timeslice", test_timeslice_threadB1_entry, RT_NULL,
2048, __current_thread->current_priority + 2, 2);
if (!tidB1)
{
LOG_E("rt_thread_create failed!");
return;
}
rt_thread_control(tidB1, RT_THREAD_CTRL_BIND_CPU, (void *)1);
ret_startup = rt_thread_startup(tidB1);
if (ret_startup != RT_EOK)
{
LOG_E("rt_thread_startup failed!");
uassert_false(1);
return ;
}
tidB2 = rt_thread_create("timeslice", test_timeslice_threadB2_entry, RT_NULL,
2048, __current_thread->current_priority + 2, 2);
if (!tidB2)
{
LOG_E("rt_thread_create failed!");
return;
}
rt_thread_control(tidB2, RT_THREAD_CTRL_BIND_CPU, (void *)1);
ret_startup = rt_thread_startup(tidB2);
if (ret_startup != RT_EOK)
{
LOG_E("rt_thread_startup failed!");
uassert_false(1);
return ;
}
do{
rt_thread_delay(2 * 20);
}while(timeslice_cntA <= 10);
rt_kprintf("A:%d,B1:%d,B2:%d\n", timeslice_cntA, timeslice_cntB1, timeslice_cntB2);
diff = abs(timeslice_cntB1 - timeslice_cntB2);
uassert_true(diff * 100 / timeslice_cntB1 < 30);
uassert_true(timeslice_cntA == 11);
}
#ifndef RT_USING_SMP
static volatile rt_uint32_t yield_count;
static void test_thread_yield_inc_entry(void *parameter)
{
rt_uint32_t loop = 0;
while (1)
{
if (loop++ > 10001)
break;
yield_count++;
rt_thread_yield();
}
}
static void test_thread_yield_entry(void *parameter)
{
rt_err_t ret_startup = -RT_ERROR;
rt_thread_t tid;
rt_uint32_t loop = 0;
rt_uint32_t count_before;
tid = rt_thread_create("inc", test_thread_yield_inc_entry, RT_NULL,
2048, 1, 10);
if (!tid)
{
LOG_E("rt_thread_create failed!");
return;
}
ret_startup = rt_thread_startup(tid);
if (ret_startup != RT_EOK)
{
LOG_E("rt_thread_startup failed!");
uassert_false(1);
return ;
}
while (1)
{
if (loop++ > 10000)
break;
count_before = yield_count;
rt_thread_yield();
if (yield_count == count_before)
{
LOG_E("yield error!");
return;
}
}
thread_yield_flag = 1;
}
void test_thread_yield_nosmp(void)
{
rt_err_t ret_startup = -RT_ERROR;
rt_thread_t tid;
yield_count = 0;
tid = rt_thread_create("chkcnt", test_thread_yield_entry, RT_NULL,
2048, 1, 10);
if (!tid)
{
LOG_E("rt_thread_create failed!");
return;
}
ret_startup = rt_thread_startup(tid);
if (ret_startup != RT_EOK)
{
LOG_E("rt_thread_startup failed!");
uassert_false(1);
return ;
}
uassert_true(thread_yield_flag == 1);
}
// static rt_uint32_t thread9_count = 0;
// static void thread9_entry(void *parameter)
// {
// while (1)
// {
// thread9_count ++;
// }
// }
// static void test_thread_suspend(void)
// {
// static rt_thread_t tid;
// rt_err_t ret_startup = -RT_ERROR;
// uint32_t count_before_suspend, count_before_resume, count_after_resume;
// tid = rt_thread_create("thread9",
// thread9_entry,
// RT_NULL,
// THREAD_STACK_SIZE,
// __current_thread->current_priority + 1,
// THREAD_TIMESLICE);
// if (tid == RT_NULL)
// {
// LOG_E("rt_thread_create failed!");
// uassert_false(tid4 == RT_NULL);
// goto __exit;
// }
// ret_startup = rt_thread_startup(tid);
// if (ret_startup != RT_EOK)
// {
// LOG_E("rt_thread_startup failed!");
// uassert_false(1);
// goto __exit;
// }
// rt_thread_delay(5);
// rt_thread_suspend(tid);
// count_before_suspend = thread9_count;
// uassert_true(count_before_suspend != 0);
// rt_thread_delay(5);
// count_before_resume = thread9_count;
// uassert_true(count_before_suspend == count_before_resume);
// rt_thread_resume(tid);
// rt_thread_delay(5);
// count_after_resume = thread9_count;
// uassert_true(count_after_resume != count_before_resume);
// __exit:
// if (tid != RT_NULL)
// {
// rt_thread_delete(tid);
// }
// return;
// }
#endif
static rt_err_t utest_tc_init(void)
{
__current_thread = rt_thread_self();
change_priority = __current_thread->current_priority + 5;
tid3_delay_pass_flag = 0;
tid3_finish_flag = 0;
tid4_finish_flag = 0;
tid6_finish_flag = 0;
entry_idle_hook_times = 0;
count = 0;
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
return RT_EOK;
}
static void testcase(void)
{
/* init, detach */
UTEST_UNIT_RUN(test_static_thread);
/* create, delete */
UTEST_UNIT_RUN(test_dynamic_thread);
/* delay */
UTEST_UNIT_RUN(test_thread_delay);
/* idle_sethook, idle_delhook */
UTEST_UNIT_RUN(test_idle_hook);
/* yield */
UTEST_UNIT_RUN(test_thread_yield);
#ifndef RT_USING_SMP
/* yield_nosmp */
UTEST_UNIT_RUN(test_thread_yield_nosmp);
/* suspend, resume */
// UTEST_UNIT_RUN(test_thread_suspend);
#endif
/* control */
UTEST_UNIT_RUN(test_thread_control);
UTEST_UNIT_RUN(test_thread_priority);
/* delay_until */
UTEST_UNIT_RUN(test_delay_until);
/* timeslice */
// UTEST_UNIT_RUN(test_timeslice); /* Can not running in Github Action QEMU */
}
UTEST_TC_EXPORT(testcase, "testcases.kernel.thread_tc", utest_tc_init, utest_tc_cleanup, 1000);
/********************* end of file ************************/

View file

@ -0,0 +1,520 @@
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-08-12 luckyzjq the first version
*/
#include <rtthread.h>
#include <stdlib.h>
#include "utest.h"
static rt_uint8_t timer_flag_oneshot[] = {
RT_TIMER_FLAG_ONE_SHOT,
RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_HARD_TIMER,
RT_TIMER_FLAG_ONE_SHOT | RT_TIMER_FLAG_SOFT_TIMER,
};
static rt_uint8_t timer_flag_periodic[] = {
RT_TIMER_FLAG_PERIODIC,
RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_HARD_TIMER,
RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER,
};
typedef struct test_timer_struct
{
struct rt_timer static_timer; /* static timer handler */
rt_timer_t dynamic_timer; /* dynamic timer pointer */
rt_tick_t expect_tick; /* expect tick */
rt_uint8_t test_flag; /* timer callback done flag */
} timer_struct;
static timer_struct timer;
#define test_static_timer_start test_static_timer_init
#define test_static_timer_stop test_static_timer_init
#define test_static_timer_detach test_static_timer_init
static void static_timer_oneshot(void *param)
{
timer_struct *timer_call;
timer_call = (timer_struct *)param;
timer_call->test_flag = RT_TRUE;
/* check expect tick */
if (rt_tick_get() - timer_call->expect_tick > 1)
{
uassert_true(RT_FALSE);
}
return;
}
static void static_timer_periodic(void *param)
{
rt_err_t result;
timer_struct *timer_call;
timer_call = (timer_struct *)param;
timer_call->test_flag = RT_TRUE;
/* check expect tick */
if (rt_tick_get() - timer_call->expect_tick > 1)
{
uassert_true(RT_FALSE);
}
/* periodic timer can stop */
result = rt_timer_stop(&timer_call->static_timer);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
return;
}
static void test_static_timer_init(void)
{
rt_err_t result;
int rand_num = rand() % 10;
/* one shot timer test */
for (int time_out = 0; time_out < rand_num; time_out++)
{
for (int i = 0; i < sizeof(timer_flag_oneshot); i++)
{
rt_timer_init(&timer.static_timer,
"static_timer",
static_timer_oneshot,
&timer,
time_out,
timer_flag_oneshot[i]);
/* calc expect tick */
timer.expect_tick = rt_tick_get() + time_out;
/* start timer */
result = rt_timer_start(&timer.static_timer);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
return;
}
/* wait for timerout */
rt_thread_delay(time_out + 1);
/* detach timer */
result = rt_timer_detach(&timer.static_timer);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
return;
}
if (timer.test_flag != RT_TRUE)
{
uassert_true(RT_FALSE);
return;
}
}
}
/* periodic timer test */
for (int time_out = 0; time_out < rand_num; time_out++)
{
for (int i = 0; i < sizeof(timer_flag_periodic); i++)
{
rt_timer_init(&timer.static_timer,
"static_timer",
static_timer_periodic,
&timer,
time_out,
timer_flag_periodic[i]);
/* calc expect tick */
timer.expect_tick = rt_tick_get() + time_out;
/* start timer */
result = rt_timer_start(&timer.static_timer);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
return;
}
/* wait for timerout */
rt_thread_delay(time_out + 1);
/* detach timer */
result = rt_timer_detach(&timer.static_timer);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
return;
}
if (timer.test_flag != RT_TRUE)
{
uassert_true(RT_FALSE);
return;
}
}
}
timer.test_flag = RT_FALSE;
uassert_true(RT_TRUE);
return;
}
static void static_timer_control(void *param)
{
rt_err_t result;
timer_struct *timer_call;
timer_call = (timer_struct *)param;
timer_call->test_flag = RT_TRUE;
/* check expect tick */
if (rt_tick_get() - timer_call->expect_tick > 1)
{
uassert_true(RT_FALSE);
}
/* periodic timer can stop */
result = rt_timer_stop(&timer_call->static_timer);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
return;
}
static void test_static_timer_control(void)
{
rt_err_t result;
int rand_num = rand() % 10;
int set_data;
int get_data;
rt_timer_init(&timer.static_timer,
"static_timer",
static_timer_control,
&timer,
5,
RT_TIMER_FLAG_PERIODIC);
/* test set data */
set_data = rand_num;
result = rt_timer_control(&timer.static_timer, RT_TIMER_CTRL_SET_TIME, &set_data);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
/* test get data */
result = rt_timer_control(&timer.static_timer, RT_TIMER_CTRL_GET_TIME, &get_data);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
/* a set of test */
if (set_data != get_data)
{
uassert_true(RT_FALSE);
}
/* calc expect tick */
timer.expect_tick = rt_tick_get() + set_data;
/* start timer */
result = rt_timer_start(&timer.static_timer);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
return;
}
rt_thread_delay(set_data + 1);
/* detach timer */
result = rt_timer_detach(&timer.static_timer);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
return;
}
if (timer.test_flag != RT_TRUE)
{
uassert_true(RT_FALSE);
return;
}
timer.test_flag = RT_FALSE;
uassert_true(RT_TRUE);
}
#ifdef RT_USING_HEAP
#define test_dynamic_timer_start test_dynamic_timer_create
#define test_dynamic_timer_stop test_dynamic_timer_create
#define test_dynamic_timer_delete test_dynamic_timer_create
static void dynamic_timer_oneshot(void *param)
{
timer_struct *timer_call;
timer_call = (timer_struct *)param;
timer_call->test_flag = RT_TRUE;
/* check expect tick */
if (rt_tick_get() - timer_call->expect_tick > 1)
{
uassert_true(RT_FALSE);
}
return;
}
static void dynamic_timer_periodic(void *param)
{
rt_err_t result;
timer_struct *timer_call;
timer_call = (timer_struct *)param;
timer_call->test_flag = RT_TRUE;
/* check expect tick */
if (rt_tick_get() - timer_call->expect_tick > 1)
{
uassert_true(RT_FALSE);
}
/* periodic timer can stop */
result = rt_timer_stop(timer_call->dynamic_timer);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
return;
}
static void test_dynamic_timer_create(void)
{
rt_err_t result;
int rand_num = rand() % 10;
/* one shot timer test */
for (int time_out = 0; time_out < rand_num; time_out++)
{
for (int i = 0; i < sizeof(timer_flag_oneshot); i++)
{
timer.dynamic_timer = rt_timer_create("dynamic_timer",
dynamic_timer_oneshot,
&timer,
time_out,
timer_flag_oneshot[i]);
/* calc expect tick */
timer.expect_tick = rt_tick_get() + time_out;
/* start timer */
result = rt_timer_start(timer.dynamic_timer);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
return;
}
/* wait for timerout */
rt_thread_delay(time_out + 1);
/* detach timer */
result = rt_timer_delete(timer.dynamic_timer);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
return;
}
if (timer.test_flag != RT_TRUE)
{
uassert_true(RT_FALSE);
return;
}
}
}
/* periodic timer test */
for (int time_out = 0; time_out < rand_num; time_out++)
{
for (int i = 0; i < sizeof(timer_flag_periodic); i++)
{
timer.dynamic_timer = rt_timer_create("dynamic_timer",
dynamic_timer_periodic,
&timer,
time_out,
timer_flag_periodic[i]);
/* calc expect tick */
timer.expect_tick = rt_tick_get() + time_out;
/* start timer */
result = rt_timer_start(timer.dynamic_timer);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
return;
}
/* wait for timerout */
rt_thread_delay(time_out + 1);
/* detach timer */
result = rt_timer_delete(timer.dynamic_timer);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
return;
}
if (timer.test_flag != RT_TRUE)
{
uassert_true(RT_FALSE);
return;
}
}
}
timer.test_flag = RT_FALSE;
uassert_true(RT_TRUE);
return;
}
static void dynamic_timer_control(void *param)
{
rt_err_t result;
timer_struct *timer_call;
timer_call = (timer_struct *)param;
timer_call->test_flag = RT_TRUE;
/* check expect tick */
if (rt_tick_get() - timer_call->expect_tick > 1)
{
uassert_true(RT_FALSE);
}
/* periodic timer can stop */
result = rt_timer_stop(timer_call->dynamic_timer);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
return;
}
static void test_dynamic_timer_control(void)
{
rt_err_t result;
int rand_num = rand() % 10;
int set_data;
int get_data;
timer.dynamic_timer = rt_timer_create("dynamic_timer",
dynamic_timer_control,
&timer,
5,
RT_TIMER_FLAG_PERIODIC);
/* test set data */
set_data = rand_num;
result = rt_timer_control(timer.dynamic_timer, RT_TIMER_CTRL_SET_TIME, &set_data);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
/* test get data */
result = rt_timer_control(timer.dynamic_timer, RT_TIMER_CTRL_GET_TIME, &get_data);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
}
/* a set of test */
if (set_data != get_data)
{
uassert_true(RT_FALSE);
}
/* calc expect tick */
timer.expect_tick = rt_tick_get() + set_data;
/* start timer */
result = rt_timer_start(timer.dynamic_timer);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
return;
}
rt_thread_delay(set_data + 1);
/* detach timer */
result = rt_timer_delete(timer.dynamic_timer);
if (RT_EOK != result)
{
uassert_true(RT_FALSE);
return;
}
if (timer.test_flag != RT_TRUE)
{
uassert_true(RT_FALSE);
return;
}
timer.test_flag = RT_FALSE;
uassert_true(RT_TRUE);
}
#endif /* RT_USING_HEAP */
static rt_err_t utest_tc_init(void)
{
timer.dynamic_timer = RT_NULL;
timer.test_flag = RT_FALSE;
return RT_EOK;
}
static rt_err_t utest_tc_cleanup(void)
{
timer.dynamic_timer = RT_NULL;
timer.test_flag = RT_FALSE;
return RT_EOK;
}
static void testcase(void)
{
UTEST_UNIT_RUN(test_static_timer_init);
UTEST_UNIT_RUN(test_static_timer_start);
UTEST_UNIT_RUN(test_static_timer_stop);
UTEST_UNIT_RUN(test_static_timer_detach);
UTEST_UNIT_RUN(test_static_timer_control);
#ifdef RT_USING_HEAP
UTEST_UNIT_RUN(test_dynamic_timer_create);
UTEST_UNIT_RUN(test_dynamic_timer_start);
UTEST_UNIT_RUN(test_dynamic_timer_stop);
UTEST_UNIT_RUN(test_dynamic_timer_delete);
UTEST_UNIT_RUN(test_dynamic_timer_control);
#endif /* RT_USING_HEAP */
}
UTEST_TC_EXPORT(testcase, "testcases.kernel.timer_tc", utest_tc_init, utest_tc_cleanup, 1000);
/*********************** end of file ****************************/