Skip to content

Commit 07fddf0

Browse files
committed
Updated test framework
1 parent 9afa304 commit 07fddf0

File tree

10 files changed

+564
-684
lines changed

10 files changed

+564
-684
lines changed

examples/utest/testcases/perf/Kconfig

Lines changed: 6 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,55 +4,21 @@ config UTEST_SYS_PERF_TC
44
bool "system performance test"
55
default n
66

7-
choice
8-
prompt "Select time reference for System Performance Testcase"
9-
default USING_TICK_AS_TIME_REF
7+
config UTEST_SYS_PERF_TC_COUNT
8+
int "Test the number of cycles"
9+
default 1000
1010
depends on UTEST_SYS_PERF_TC
1111

12-
config USING_HWTIME_AS_TIME_REF
13-
bool "Use hardware timer as time reference"
14-
depends on RT_USING_HWTIMER
15-
16-
config USING_TICK_AS_TIME_REF
17-
bool "Use system tick as time reference"
18-
19-
endchoice
20-
2112
config UTEST_HWTIMER_DEV_NAME
2213
string "Hardware timer device name"
2314
default "timer0"
24-
depends on USING_HWTIME_AS_TIME_REF && UTEST_SYS_PERF_TC
15+
depends on RT_USING_HWTIMER && UTEST_SYS_PERF_TC
2516
help
26-
Specify the hardware timer device name used for context switch testing (e.g., timer11).
27-
28-
config UTEST_SYS_CONTEXT_SWITCH
29-
bool "system context switch test"
30-
default n
31-
depends on UTEST_SYS_PERF_TC
17+
Specify the hardware timer device name used for context switch testing (e.g., timer0).
3218

3319
config UTEST_SYS_IRQ_LATENCY
3420
bool "system IRQ LATENCY test"
3521
default n
36-
depends on RT_USING_HWTIMER && USING_HWTIME_AS_TIME_REF && UTEST_SYS_PERF_TC
37-
38-
config UTEST_SYS_THREAD_SEM
39-
bool "system thread semaphore tests"
40-
default n
41-
depends on UTEST_SYS_PERF_TC
42-
43-
config UTEST_SYS_THREAD_EVENT
44-
bool "system thread event tests"
45-
default n
46-
depends on UTEST_SYS_PERF_TC
47-
48-
config UTEST_SYS_THREAD_MBOX
49-
bool "system thread mbox tests"
50-
default n
51-
depends on UTEST_SYS_PERF_TC
52-
53-
config UTEST_SYS_THREAD_MQ
54-
bool "system thread messagequeue tests"
55-
default n
56-
depends on UTEST_SYS_PERF_TC
22+
depends on RT_USING_HWTIMER && UTEST_SYS_PERF_TC
5723

5824
endmenu

examples/utest/testcases/perf/SConscript

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,11 @@ Import('rtconfig')
22
from building import *
33

44
cwd = GetCurrentDir()
5-
src = []
5+
src = Glob('*.c')
66
CPPPATH = [cwd]
77

8-
if GetDepend(['UTEST_SYS_CONTEXT_SWITCH']):
9-
src += ['context_switch_tc.c']
10-
11-
if GetDepend(['UTEST_SYS_IRQ_LATENCY']):
12-
src += ['irq_latency_tc.c']
13-
14-
if GetDepend(['UTEST_SYS_THREAD_SEM']):
15-
src += ['thread_sem_tc.c']
16-
17-
if GetDepend(['UTEST_SYS_THREAD_EVENT']):
18-
src += ['thread_event_tc.c']
19-
20-
if GetDepend(['UTEST_SYS_THREAD_MBOX']):
21-
src += ['thread_mbox_tc.c']
22-
23-
if GetDepend(['UTEST_SYS_THREAD_MQ']):
24-
src += ['thread_mq_tc.c']
8+
# if GetDepend(['UTEST_SYS_IRQ_LATENCY']):
9+
# src += ['irq_latency_tc.c']
2510

2611
group = DefineGroup('utestcases', src, depend = ['UTEST_SYS_PERF_TC'], CPPPATH = CPPPATH)
2712

examples/utest/testcases/perf/context_switch_tc.c

Lines changed: 112 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,75 @@
1313
#include <rtdevice.h>
1414
#include <utest.h>
1515
#include <utest_assert.h>
16+
#include <perf_tc.h>
17+
18+
typedef struct rt_perf_array
19+
{
20+
rt_uint32_t count;
21+
rt_uint32_t *raw_times;
22+
rt_uint32_t *local_times;
23+
rt_uint32_t *net_times;
24+
} rt_perf_array_t;
1625

1726
static rt_sem_t sem1, sem2;
18-
static rt_thread_t thread1, thread2;
19-
#define THREAD_STACK_SIZE 1024
20-
#define THREAD_PRIORITY 10
21-
#define THREAD_TIMESLICE 5
27+
static rt_sem_t complete_sem = RT_NULL;
28+
29+
void rt_perf_array_destroy(rt_perf_array_t *arr)
30+
{
31+
if (arr)
32+
{
33+
if (arr->raw_times) rt_free(arr->raw_times);
34+
if (arr->local_times) rt_free(arr->local_times);
35+
if (arr->net_times) rt_free(arr->net_times);
36+
rt_free(arr);
37+
}
38+
}
2239

23-
#define SWITCH_COUNT 1000 /* Number of context switches */
40+
rt_perf_array_t *rt_perf_array_create(rt_uint32_t count)
41+
{
42+
rt_perf_array_t *arr = rt_calloc(1, sizeof(rt_perf_array_t));
43+
if (!arr)
44+
return RT_NULL;
45+
46+
arr->count = count;
47+
arr->raw_times = rt_calloc(count, sizeof(rt_uint32_t));
48+
arr->local_times = rt_calloc(count, sizeof(rt_uint32_t));
49+
arr->net_times = rt_calloc(count, sizeof(rt_uint32_t));
2450

25-
#ifdef USING_HWTIME_AS_TIME_REF
26-
static rt_device_t hw_dev = RT_NULL;
51+
if (!arr->raw_times || !arr->local_times || !arr->net_times)
52+
{
53+
rt_perf_array_destroy(arr);
54+
return RT_NULL;
55+
}
2756

28-
static rt_size_t get_timer_us(rt_hwtimerval_t *timeout_s)
57+
return arr;
58+
}
59+
60+
void rt_perf_array_compute(rt_perf_array_t *arr, rt_perf_t *perf)
2961
{
30-
if (hw_dev)
31-
return rt_device_read(hw_dev, 0, timeout_s, sizeof(rt_hwtimerval_t));
32-
return 0;
62+
rt_uint32_t i;
63+
rt_uint32_t tot_time = 0;
64+
rt_uint32_t max_time = 0;
65+
rt_uint32_t min_time = 0xFFFFFFFF;
66+
67+
for (i = 0; i < arr->count; i++)
68+
{
69+
rt_uint32_t net = (arr->raw_times[i] > arr->local_times[i]) ?
70+
(arr->raw_times[i] - arr->local_times[i]) : 0;
71+
arr->net_times[i] = net;
72+
73+
tot_time += net;
74+
if (net > max_time) max_time = net;
75+
if (net < min_time) min_time = net;
76+
}
77+
78+
perf->count = arr->count;
79+
perf->tot_time = tot_time;
80+
perf->max_time = max_time;
81+
perf->min_time = min_time;
3382
}
34-
#endif
3583

36-
static void thread1_entry(void *parameter)
84+
static void perf_thread_event1(void *parameter)
3785
{
3886
while (1)
3987
{
@@ -42,136 +90,83 @@ static void thread1_entry(void *parameter)
4290
}
4391
}
4492

45-
static void thread2_entry(void *parameter)
93+
static void perf_thread_event2(void *parameter)
4694
{
47-
rt_uint32_t total_time = 0;
48-
rt_uint32_t sem_op_time = 0;
95+
rt_perf_t *perf = (rt_perf_t *)parameter;
96+
rt_perf_t *perf_local = (rt_perf_t *)rt_calloc(1,sizeof(rt_perf_t));
4997
rt_uint32_t i;
50-
#ifdef USING_HWTIME_AS_TIME_REF
51-
rt_hwtimerval_t start_time, end_time;
52-
rt_uint16_t ret;
53-
/* Getting Signal Time */
54-
ret = get_timer_us(&start_time);
55-
for (i = 0; i < SWITCH_COUNT; i++)
56-
{
57-
rt_sem_take(sem2, RT_WAITING_FOREVER);
58-
rt_sem_release(sem2);
59-
}
60-
ret +=get_timer_us(&end_time);
61-
sem_op_time = (end_time.sec - start_time.sec) * 1000000u + (end_time.usec - start_time.usec);
6298

63-
ret += get_timer_us(&start_time);
64-
for (i = 0; i < SWITCH_COUNT; i++)
99+
rt_perf_array_t *perf_arr = rt_perf_array_create(UTEST_SYS_PERF_TC_COUNT);
100+
if (!perf_arr)
65101
{
66-
rt_sem_take(sem2, RT_WAITING_FOREVER);
67-
rt_sem_release(sem1);
102+
LOG_E("Failed to allocate performance arrays");
103+
return;
68104
}
69-
ret +=get_timer_us(&end_time);
70-
total_time = (end_time.sec - start_time.sec) * 1000000u + (end_time.usec - start_time.usec);
71-
#else
72-
rt_uint32_t start_time, end_time;
73-
/* Getting Signal Time */
74-
start_time = rt_tick_get();
75-
for (i = 0; i < SWITCH_COUNT; i++)
105+
106+
for (i = 0; i < UTEST_SYS_PERF_TC_COUNT; i++)
76107
{
108+
rt_perf_start(perf_local);
77109
rt_sem_take(sem2, RT_WAITING_FOREVER);
78110
rt_sem_release(sem2);
111+
rt_perf_stop(perf_local);
112+
perf_arr->local_times[i] = perf_local->real_time;
79113
}
80-
end_time = rt_tick_get();
81-
sem_op_time = (end_time - start_time) / RT_TICK_PER_SECOND;
82-
sem_op_time += ((end_time - start_time) % RT_TICK_PER_SECOND) * (1000000u / RT_TICK_PER_SECOND);
83114

84-
start_time = rt_tick_get();
85-
for (i = 0; i < SWITCH_COUNT; i++)
115+
for (i = 0; i < UTEST_SYS_PERF_TC_COUNT; i++)
86116
{
87-
rt_sem_take(sem2, RT_WAITING_FOREVER);
88-
rt_sem_release(sem1);
117+
rt_perf_start(perf);
118+
rt_sem_take(sem2, RT_WAITING_FOREVER);
119+
rt_sem_release(sem1);
120+
rt_perf_stop(perf);
121+
perf_arr->raw_times[i] = perf->real_time;
89122
}
90-
end_time = rt_tick_get();
91-
total_time = (end_time - start_time) / RT_TICK_PER_SECOND;
92-
total_time += ((end_time - start_time) % RT_TICK_PER_SECOND) * (1000000u / RT_TICK_PER_SECOND);
93-
#endif
94-
95-
rt_uint32_t single_switch_time = total_time / SWITCH_COUNT; /* Total single switching time */
96-
rt_uint32_t single_sem_op_time = sem_op_time / SWITCH_COUNT; /* Single semaphore operation time */
97-
rt_uint32_t context_switch_time = single_switch_time - single_sem_op_time; /* Context switching time */
98123

99-
LOG_I("Total time for %d switches: %d us", SWITCH_COUNT, total_time);
100-
LOG_I("Single switch time (including semaphore): %d us", single_switch_time);
101-
LOG_I("Semaphore operation time: %d us", single_sem_op_time);
102-
LOG_I("Pure context switch time: %d us", context_switch_time);
124+
rt_perf_array_compute(perf_arr, perf);
125+
rt_perf_array_destroy(perf_arr);
126+
rt_free(perf_local);
127+
rt_sem_release(complete_sem);
103128
}
104129

105-
void context_switch_test(void)
130+
rt_err_t context_switch_test(rt_perf_t *perf)
106131
{
107-
thread1 = rt_thread_create("thread1", thread1_entry, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
108-
if (thread1 != RT_NULL)
109-
{
110-
rt_thread_startup(thread1);
111-
}
132+
rt_thread_t thread1 = RT_NULL;
133+
rt_thread_t thread2 = RT_NULL;
112134

113-
thread2 = rt_thread_create("thread2", thread2_entry, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
114-
if (thread2 != RT_NULL)
115-
{
116-
rt_thread_startup(thread2);
117-
}
118-
}
135+
# if __STDC_VERSION__ >= 199901L
136+
rt_strcpy(perf->name,__func__);
137+
#else
138+
rt_strcpy(perf->name,"context_switch_test");
139+
#endif
119140

120-
static rt_err_t utest_tc_init(void)
121-
{
122-
int ret = RT_EOK;
123-
#ifdef USING_HWTIME_AS_TIME_REF
124-
rt_hwtimerval_t timeout_s;
141+
sem1 = rt_sem_create("sem1", 1, RT_IPC_FLAG_FIFO);
142+
sem2 = rt_sem_create("sem2", 0, RT_IPC_FLAG_FIFO);
143+
complete_sem = rt_sem_create("complete_sem", 0, RT_IPC_FLAG_FIFO);
125144

126-
hw_dev = rt_device_find(UTEST_HWTIMER_DEV_NAME);
127-
if (hw_dev == RT_NULL)
145+
thread1 = rt_thread_create("perf_thread_event1", perf_thread_event1, perf,
146+
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
147+
if (thread1 == RT_NULL)
128148
{
129-
ret = RT_ERROR;
130-
LOG_E("hwtimer sample run failed! can't find %s device!", UTEST_HWTIMER_DEV_NAME);
131-
return ret;
149+
LOG_E("perf_thread_event1 create failed.");
150+
return -RT_ERROR;
132151
}
133152

134-
ret = rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR);
135-
if (ret != RT_EOK)
153+
thread2 = rt_thread_create("perf_thread_event2", perf_thread_event2, perf,
154+
THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
155+
if (thread2 == RT_NULL)
136156
{
137-
LOG_E("open %s device failed!", UTEST_HWTIMER_DEV_NAME);
138-
return ret;
157+
LOG_E("perf_thread_event2 create failed.");
158+
return -RT_ERROR;
139159
}
140160

141-
timeout_s.sec = 5; /* s */
142-
timeout_s.usec = 0; /* us */
143-
if (rt_device_write(hw_dev, 0, &timeout_s, sizeof(rt_hwtimerval_t)) != sizeof(rt_hwtimerval_t))
144-
{
145-
ret = RT_ERROR;
146-
LOG_E("set timeout value failed");
147-
return ret;
148-
}
149-
#endif
150-
sem1 = rt_sem_create("sem1", 1, RT_IPC_FLAG_FIFO);
151-
sem2 = rt_sem_create("sem2", 0, RT_IPC_FLAG_FIFO);
152-
if (sem1 == RT_NULL || sem2 == RT_NULL)
153-
{
154-
ret = RT_ERROR;
155-
LOG_E("Semaphore create failed!");
156-
return ret;
157-
}
158-
return ret;
159-
}
161+
rt_thread_startup(thread1);
162+
rt_thread_startup(thread2);
160163

161-
static rt_err_t utest_tc_cleanup(void)
162-
{
163-
if (thread1) rt_thread_delete(thread1);
164-
if(sem1) rt_sem_delete(sem1);
165-
if(sem2) rt_sem_delete(sem2);
166-
#ifdef USING_HWTIME_AS_TIME_REF
167-
if(hw_dev) rt_device_close(hw_dev);
168-
#endif
169-
return RT_EOK;
170-
}
164+
rt_sem_take(complete_sem, RT_WAITING_FOREVER);
165+
rt_thread_delete(thread1);
166+
rt_sem_delete(complete_sem);
167+
rt_sem_delete(sem1);
168+
rt_sem_delete(sem2);
171169

172-
static void testcase(void)
173-
{
174-
UTEST_UNIT_RUN(context_switch_test);
170+
return RT_EOK;
175171
}
176172

177-
UTEST_TC_EXPORT(testcase, "testcase.pref.context", utest_tc_init, utest_tc_cleanup, 10);

0 commit comments

Comments
 (0)