Skip to content

Commit ead4f50

Browse files
committed
add sys pref frameworks
1 parent a1e8651 commit ead4f50

File tree

5 files changed

+292
-0
lines changed

5 files changed

+292
-0
lines changed

examples/utest/testcases/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ rsource "posix/Kconfig"
1717
rsource "mm/Kconfig"
1818
rsource "tmpfs/Kconfig"
1919
rsource "smp_call/Kconfig"
20+
rsource "perf/Kconfig"
2021
endif
2122

2223
endmenu
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
menu "System Performance Testcase"
2+
3+
config UTEST_SYS_PERF_TC
4+
bool "system performance test"
5+
default n
6+
7+
config UTEST_SYS_PERF_TC_COUNT
8+
int "Test the number of cycles"
9+
default 1000
10+
depends on UTEST_SYS_PERF_TC
11+
12+
config UTEST_HWTIMER_DEV_NAME
13+
string "Hardware timer device name"
14+
default "timer0"
15+
depends on RT_USING_HWTIMER && UTEST_SYS_PERF_TC
16+
help
17+
Specify the hardware timer device name used for context switch testing (e.g., timer0).
18+
19+
config UTEST_SYS_IRQ_LATENCY
20+
bool "system IRQ LATENCY test"
21+
default n
22+
depends on RT_USING_HWTIMER && UTEST_SYS_PERF_TC
23+
24+
endmenu
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Import('rtconfig')
2+
from building import *
3+
4+
cwd = GetCurrentDir()
5+
src = Glob('*.c')
6+
CPPPATH = [cwd]
7+
8+
group = DefineGroup('utestcases', src, depend = ['UTEST_SYS_PERF_TC'], CPPPATH = CPPPATH)
9+
10+
Return('group')
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
/*
2+
* Copyright (c) 2006-2025, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2025-07-03 rcitach test case for irq latency
9+
*/
10+
11+
#include <rtthread.h>
12+
#include <rtdevice.h>
13+
#include <rtservice.h>
14+
#include <utest.h>
15+
#include <utest_assert.h>
16+
#include <perf_tc.h>
17+
18+
#define RET_INT 0
19+
#define RET_DECIMALS 1
20+
21+
#define GET_INT(num) split_double(num, RET_INT)
22+
#define GET_DECIMALS(num) split_double(num, RET_DECIMALS)
23+
24+
static rt_device_t hw_dev = RT_NULL;
25+
static rt_hwtimerval_t timeout_s = {0};
26+
27+
typedef rt_err_t (*testcase_function)(rt_perf_t *perf);
28+
testcase_function test_func_ptrs[] =
29+
{
30+
context_switch_test,
31+
rt_perf_thread_sem,
32+
rt_perf_thread_event,
33+
rt_perf_thread_mq,
34+
rt_perf_thread_mbox,
35+
rt_perf_irq_latency, /* Timer Interrupt Source */
36+
RT_NULL
37+
};
38+
39+
static rt_uint32_t rt_perf_get_timer_us(void)
40+
{
41+
rt_hwtimerval_t timer_val = {0};
42+
if (hw_dev && rt_device_read(hw_dev, 0, &timer_val, sizeof(rt_hwtimerval_t)))
43+
{
44+
return (rt_uint32_t)(timer_val.sec * 1000000u + timer_val.usec); /* return us */
45+
}
46+
return 0;
47+
}
48+
49+
void rt_perf_start_impl(rt_perf_t *perf, rt_hwtimerval_t *timeout)
50+
{
51+
if (hw_dev)
52+
{
53+
if (timeout == RT_NULL)
54+
timeout = &timeout_s;
55+
rt_device_write(hw_dev, 0, timeout, sizeof(rt_hwtimerval_t));
56+
}
57+
perf->begin_time = rt_perf_get_timer_us();
58+
}
59+
60+
void rt_perf_stop(rt_perf_t *perf)
61+
{
62+
perf->real_time = rt_perf_get_timer_us() - perf->begin_time;
63+
64+
if(perf->local_modify) perf->local_modify(perf);
65+
if (perf->real_time > perf->max_time)
66+
{
67+
perf->max_time = perf->real_time;
68+
}
69+
70+
if (perf->real_time < perf->min_time)
71+
{
72+
perf->min_time = perf->real_time;
73+
}
74+
75+
perf->count++;
76+
perf->tot_time += perf->real_time;
77+
78+
if(hw_dev)
79+
rt_device_control(hw_dev, HWTIMER_CTRL_STOP, NULL);
80+
}
81+
82+
static rt_int32_t split_double(double num, rt_uint32_t type)
83+
{
84+
if (type == RET_INT)
85+
{
86+
return (rt_int32_t)num;
87+
}
88+
else if (type == RET_DECIMALS)
89+
{
90+
return (rt_int32_t)((num - (rt_int32_t)num) * 10000);
91+
}
92+
else
93+
{
94+
return (-1);
95+
}
96+
97+
return (-1);
98+
}
99+
100+
void rt_perf_dump( rt_perf_t *perf)
101+
{
102+
static rt_uint32_t test_index = 1;
103+
char avg_str[10] = {0};
104+
if(perf->dump_head)
105+
{
106+
rt_kprintf("Test No | Test Name | Count | Total Time (us) | Max Time (us) | Min Time (us) | Avg Time (us)\n");
107+
rt_kprintf("--------|----------------------|-------|-----------------|---------------|---------------|--------------\n");
108+
perf->dump_head = RT_FALSE;
109+
}
110+
111+
if (perf->count)
112+
perf->avg_time = (double)perf->tot_time / perf->count;
113+
else
114+
perf->avg_time = 0.0;
115+
116+
rt_sprintf(avg_str, "%u.%04u", GET_INT(perf->avg_time), GET_DECIMALS(perf->avg_time));
117+
118+
rt_kprintf("%7u | %-20s | %5u | %15u | %13u | %13u | %12s\n",
119+
test_index++,
120+
perf->name,
121+
perf->count,
122+
perf->tot_time,
123+
perf->max_time,
124+
perf->min_time,
125+
avg_str);
126+
}
127+
128+
static void rt_perf_clear(rt_perf_t *perf)
129+
{
130+
perf->local_modify = NULL;
131+
perf->begin_time = 0;
132+
perf->real_time = 0;
133+
perf->tot_time = 0;
134+
perf->max_time = 0;
135+
perf->min_time = RT_UINT32_MAX;
136+
perf->count = 0;
137+
perf->avg_time = 0;
138+
perf->tmp_time = 0;
139+
}
140+
141+
static void rt_perf_all_test(void)
142+
{
143+
144+
rt_perf_t *perf_data = rt_malloc(sizeof(rt_perf_t));
145+
if (perf_data == RT_NULL)
146+
{
147+
return;
148+
}
149+
perf_data->lock = rt_mutex_create("perf", RT_IPC_FLAG_PRIO);
150+
perf_data->dump_head = RT_TRUE;
151+
rt_kprintf("\n === Performance Test Results Start ===\n");
152+
for (int i = 0; test_func_ptrs[i] != RT_NULL; i++)
153+
{
154+
rt_perf_clear(perf_data);
155+
if (test_func_ptrs[i](perf_data) != RT_EOK)
156+
{
157+
LOG_E("%s test fail",perf_data->name);
158+
continue;
159+
}
160+
}
161+
rt_kprintf("\n === Performance Test Results End ===\n");
162+
rt_mutex_delete(perf_data->lock);
163+
rt_free(perf_data);
164+
}
165+
166+
static rt_err_t utest_tc_init(void)
167+
{
168+
int ret = RT_EOK;
169+
170+
hw_dev = rt_device_find(UTEST_HWTIMER_DEV_NAME);
171+
if (hw_dev == RT_NULL)
172+
{
173+
ret = RT_ERROR;
174+
LOG_E("hwtimer sample run failed! can't find %s device!", UTEST_HWTIMER_DEV_NAME);
175+
return ret;
176+
}
177+
ret = rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR);
178+
if (ret != RT_EOK)
179+
{
180+
LOG_E("open %s device failed!", UTEST_HWTIMER_DEV_NAME);
181+
return ret;
182+
}
183+
184+
timeout_s.sec = 10; /* No modification is necessary here, use the fixed value */
185+
timeout_s.usec = 0;
186+
187+
return ret;
188+
}
189+
190+
static rt_err_t utest_tc_cleanup(void)
191+
{
192+
if(hw_dev) rt_device_close(hw_dev);
193+
return RT_EOK;
194+
}
195+
196+
static void testcase(void)
197+
{
198+
UTEST_UNIT_RUN(rt_perf_all_test);
199+
}
200+
201+
UTEST_TC_EXPORT(testcase, "testcase.pref.all", utest_tc_init, utest_tc_cleanup, 10);
202+
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright (c) 2006-2025, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2025-07-03 rcitach test case
9+
*/
10+
11+
#ifndef PERF_TC_H__
12+
#define PERF_TC_H__
13+
14+
#include <rtthread.h>
15+
#include <rtdevice.h>
16+
#include <rtservice.h>
17+
#include <rttypes.h>
18+
19+
#define THREAD_STACK_SIZE 2048
20+
#define THREAD_PRIORITY 10
21+
#define THREAD_TIMESLICE 5
22+
typedef struct rt_perf
23+
{
24+
char name[64];
25+
volatile rt_uint32_t begin_time;
26+
volatile rt_uint32_t real_time;
27+
volatile rt_uint32_t tot_time;
28+
volatile rt_uint32_t max_time;
29+
volatile rt_uint32_t min_time;
30+
volatile rt_uint32_t count;
31+
volatile double avg_time;
32+
volatile rt_uint32_t tmp_time; /* Temporary data */
33+
rt_mutex_t lock;
34+
void (*local_modify)(struct rt_perf *perf);
35+
rt_bool_t dump_head;
36+
} rt_perf_t;
37+
38+
void rt_perf_start_impl(rt_perf_t *perf, rt_hwtimerval_t *timeout);
39+
void rt_perf_stop(rt_perf_t *perf);
40+
void rt_perf_dump( rt_perf_t *perf);
41+
42+
static inline void rt_perf_start(rt_perf_t *perf)
43+
{
44+
rt_perf_start_impl(perf, RT_NULL);
45+
}
46+
47+
rt_err_t context_switch_test(rt_perf_t *perf);
48+
rt_err_t rt_perf_irq_latency(rt_perf_t *perf);
49+
rt_err_t rt_perf_thread_sem(rt_perf_t *perf);
50+
rt_err_t rt_perf_thread_event(rt_perf_t *perf);
51+
rt_err_t rt_perf_thread_mq(rt_perf_t *perf);
52+
rt_err_t rt_perf_thread_mbox(rt_perf_t *perf);
53+
54+
#endif /* PERF_TC_H__ */
55+

0 commit comments

Comments
 (0)