Skip to content

Commit a214186

Browse files
committed
add context switch test code
1 parent b2ef50c commit a214186

File tree

1 file changed

+166
-0
lines changed

1 file changed

+166
-0
lines changed
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
#include <rtthread.h>
2+
#include <rthw.h>
3+
#include <rtdevice.h>
4+
#include <utest.h>
5+
#include <utest_assert.h>
6+
7+
static rt_sem_t sem1, sem2;
8+
static rt_thread_t thread1, thread2;
9+
#define THREAD_STACK_SIZE 1024
10+
#define THREAD_PRIORITY 10
11+
#define THREAD_TIMESLICE 5
12+
13+
#define SWITCH_COUNT 1000 /* Number of context switches */
14+
15+
#ifdef USING_HWTIME_AS_TIME_REF
16+
static rt_device_t hw_dev = RT_NULL;
17+
18+
static rt_size_t get_timer_us(rt_hwtimerval_t *timeout_s)
19+
{
20+
if (hw_dev)
21+
return rt_device_read(hw_dev, 0, timeout_s, sizeof(rt_hwtimerval_t));
22+
return 0;
23+
}
24+
#endif
25+
26+
static void thread1_entry(void *parameter)
27+
{
28+
while (1)
29+
{
30+
rt_sem_take(sem1, RT_WAITING_FOREVER);
31+
rt_sem_release(sem2);
32+
}
33+
}
34+
35+
static void thread2_entry(void *parameter)
36+
{
37+
rt_uint32_t total_time = 0;
38+
rt_uint32_t sem_op_time = 0;
39+
rt_uint32_t i;
40+
#ifdef USING_HWTIME_AS_TIME_REF
41+
rt_hwtimerval_t start_time, end_time;
42+
rt_uint16_t ret;
43+
/* Getting Signal Time */
44+
ret = get_timer_us(&start_time);
45+
for (i = 0; i < SWITCH_COUNT; i++)
46+
{
47+
rt_sem_take(sem2, RT_WAITING_FOREVER);
48+
rt_sem_release(sem2);
49+
}
50+
ret +=get_timer_us(&end_time);
51+
sem_op_time = (end_time.sec - start_time.sec) * 1000 + (end_time.usec - start_time.usec);
52+
53+
ret += get_timer_us(&start_time);
54+
for (i = 0; i < SWITCH_COUNT; i++)
55+
{
56+
rt_sem_take(sem2, RT_WAITING_FOREVER);
57+
rt_sem_release(sem1);
58+
}
59+
ret +=get_timer_us(&end_time);
60+
total_time = (end_time.sec - start_time.sec) * 1000 + (end_time.usec - start_time.usec);
61+
#else
62+
rt_uint32_t start_time, end_time;
63+
/* Getting Signal Time */
64+
start_time = rt_tick_get();
65+
for (i = 0; i < SWITCH_COUNT; i++)
66+
{
67+
rt_sem_take(sem2, RT_WAITING_FOREVER);
68+
rt_sem_release(sem2);
69+
}
70+
end_time = rt_tick_get();
71+
sem_op_time = (end_time - start_time) * (1000u / RT_TICK_PER_SECOND) * 1000u;
72+
73+
start_time = rt_tick_get();
74+
for (i = 0; i < SWITCH_COUNT; i++)
75+
{
76+
rt_sem_take(sem2, RT_WAITING_FOREVER);
77+
rt_sem_release(sem1);
78+
}
79+
end_time = rt_tick_get();
80+
total_time = (end_time - start_time) * (1000u / RT_TICK_PER_SECOND) * 1000u;
81+
#endif
82+
83+
rt_uint32_t single_switch_time = total_time / SWITCH_COUNT; /* Total single switching time */
84+
rt_uint32_t single_sem_op_time = sem_op_time / SWITCH_COUNT; /* Single semaphore operation time */
85+
rt_uint32_t context_switch_time = single_switch_time - single_sem_op_time; /* Context switching time */
86+
87+
rt_kprintf("Total time for %d switches: %d us\n", SWITCH_COUNT, total_time);
88+
rt_kprintf("Single switch time (including semaphore): %d us\n", single_switch_time);
89+
rt_kprintf("Semaphore operation time: %d us\n", single_sem_op_time);
90+
rt_kprintf("Pure context switch time: %d us\n", context_switch_time);
91+
}
92+
93+
void context_switch_test(void)
94+
{
95+
96+
thread1 = rt_thread_create("thread1", thread1_entry, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
97+
if (thread1 != RT_NULL)
98+
{
99+
rt_thread_startup(thread1);
100+
}
101+
102+
thread2 = rt_thread_create("thread2", thread2_entry, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
103+
if (thread2 != RT_NULL)
104+
{
105+
rt_thread_startup(thread2);
106+
}
107+
}
108+
109+
static rt_err_t utest_tc_init(void)
110+
{
111+
int ret = RT_EOK;
112+
#ifdef USING_HWTIME_AS_TIME_REF
113+
rt_hwtimerval_t timeout_s;
114+
115+
hw_dev = rt_device_find(UTEST_HWTIMER_DEV_NAME);
116+
if (hw_dev == RT_NULL)
117+
{
118+
ret = RT_ERROR;
119+
rt_kprintf("hwtimer sample run failed! can't find %s device!\n", UTEST_HWTIMER_DEV_NAME);
120+
return ret;
121+
}
122+
123+
ret = rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR);
124+
if (ret != RT_EOK)
125+
{
126+
rt_kprintf("open %s device failed!\n", UTEST_HWTIMER_DEV_NAME);
127+
return ret;
128+
}
129+
130+
timeout_s.sec = 5; /* s */
131+
timeout_s.usec = 0; /* us */
132+
if (rt_device_write(hw_dev, 0, &timeout_s, sizeof(rt_hwtimerval_t)) != sizeof(rt_hwtimerval_t))
133+
{
134+
ret = RT_ERROR;
135+
rt_kprintf("set timeout value failed\n");
136+
return ret;
137+
}
138+
#endif
139+
sem1 = rt_sem_create("sem1", 1, RT_IPC_FLAG_FIFO);
140+
sem2 = rt_sem_create("sem2", 0, RT_IPC_FLAG_FIFO);
141+
if (sem1 == RT_NULL || sem2 == RT_NULL)
142+
{
143+
ret = RT_ERROR;
144+
rt_kprintf("Semaphore create failed!\n");
145+
return ret;
146+
}
147+
return ret;
148+
}
149+
150+
static rt_err_t utest_tc_cleanup(void)
151+
{
152+
if (thread1) rt_thread_delete(thread1);
153+
if(sem1) rt_sem_delete(sem1);
154+
if(sem2) rt_sem_delete(sem2);
155+
#ifdef USING_HWTIME_AS_TIME_REF
156+
if(hw_dev) rt_device_close(hw_dev);
157+
#endif
158+
return RT_EOK;
159+
}
160+
161+
static void testcase(void)
162+
{
163+
UTEST_UNIT_RUN(context_switch_test);
164+
}
165+
166+
UTEST_TC_EXPORT(testcase, "testcase.pref.context", utest_tc_init, utest_tc_cleanup, 10);

0 commit comments

Comments
 (0)