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 context_switch
9 */
10
11 #include <rtthread.h>
12 #include <rthw.h>
13 #include <rtdevice.h>
14 #include <utest.h>
15 #include <utest_assert.h>
16 #include <perf_tc.h>
17
18 static rt_sem_t sem1, sem2;
19 static rt_sem_t complete_sem = RT_NULL;
20
local_modify_time(rt_perf_t * perf)21 static void local_modify_time(rt_perf_t *perf)
22 {
23 if(perf)
24 perf->real_time = perf->real_time - perf->tmp_time;
25 }
26
perf_thread_event1(void * parameter)27 static void perf_thread_event1(void *parameter)
28 {
29 while (1)
30 {
31 rt_sem_take(sem1, RT_WAITING_FOREVER);
32 rt_sem_release(sem2);
33 }
34 }
35
perf_thread_event2(void * parameter)36 static void perf_thread_event2(void *parameter)
37 {
38 rt_perf_t *perf = (rt_perf_t *)parameter;
39
40 for (rt_uint32_t i = 0; i < UTEST_SYS_PERF_TC_COUNT; i++)
41 {
42 perf->tmp_time = 0;
43 rt_perf_start(perf);
44 rt_sem_take(sem2, RT_WAITING_FOREVER);
45 rt_sem_release(sem2);
46 rt_perf_stop(perf);
47
48 rt_mutex_take(perf->lock,RT_WAITING_FOREVER);
49 perf->count -= 1;
50 perf->tmp_time = perf->real_time;
51 rt_mutex_release(perf->lock);
52
53 rt_perf_start(perf);
54 rt_sem_take(sem2, RT_WAITING_FOREVER);
55 rt_sem_release(sem1);
56 rt_perf_stop(perf);
57 }
58 rt_sem_release(complete_sem);
59 }
60
context_switch_test(rt_perf_t * perf)61 rt_err_t context_switch_test(rt_perf_t *perf)
62 {
63 rt_thread_t thread1 = RT_NULL;
64 rt_thread_t thread2 = RT_NULL;
65
66 # if __STDC_VERSION__ >= 199901L
67 rt_strcpy(perf->name,__func__);
68 #else
69 rt_strcpy(perf->name,"context_switch_test");
70 #endif
71
72 perf->local_modify = local_modify_time;
73 sem1 = rt_sem_create("sem1", 1, RT_IPC_FLAG_FIFO);
74 sem2 = rt_sem_create("sem2", 0, RT_IPC_FLAG_FIFO);
75 complete_sem = rt_sem_create("complete_sem", 0, RT_IPC_FLAG_FIFO);
76
77 thread1 = rt_thread_create("perf_thread_event1", perf_thread_event1, perf,
78 THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
79 if (thread1 == RT_NULL)
80 {
81 LOG_E("perf_thread_event1 create failed.");
82 return -RT_ERROR;
83 }
84
85 thread2 = rt_thread_create("perf_thread_event2", perf_thread_event2, perf,
86 THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
87 if (thread2 == RT_NULL)
88 {
89 LOG_E("perf_thread_event2 create failed.");
90 return -RT_ERROR;
91 }
92
93 rt_thread_startup(thread1);
94 rt_thread_startup(thread2);
95
96 rt_sem_take(complete_sem, RT_WAITING_FOREVER);
97
98 rt_perf_dump(perf);
99 rt_thread_delete(thread1);
100 rt_sem_delete(complete_sem);
101 rt_sem_delete(sem1);
102 rt_sem_delete(sem2);
103
104 return RT_EOK;
105 }
106
107