Skip to content

Commit 7b34f1c

Browse files
committed
add thread sem test code
1 parent 141e7c8 commit 7b34f1c

File tree

1 file changed

+187
-0
lines changed

1 file changed

+187
-0
lines changed
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
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 semaphore
9+
*/
10+
11+
#include <rtthread.h>
12+
#include <rthw.h>
13+
#include <rtdevice.h>
14+
#include <utest.h>
15+
#include <utest_assert.h>
16+
17+
#define PERF_COUNT 1000
18+
static rt_sem_t perf_thread_sem = RT_NULL;
19+
static rt_event_t perf_thread_event = RT_NULL;
20+
volatile static uint16_t thread_event_count = 0;
21+
22+
#define EVENT_FLAG (1 << 0)
23+
24+
#define THREAD_STACK_SIZE 1024
25+
#define THREAD_PRIORITY 10
26+
#define THREAD_TIMESLICE 5
27+
28+
struct perf_time
29+
{
30+
rt_uint32_t start_time;
31+
rt_uint32_t end_time;
32+
rt_uint32_t use_time;
33+
};
34+
static struct perf_time use_time[PERF_COUNT];
35+
36+
#ifdef USING_HWTIME_AS_TIME_REF
37+
static rt_device_t hw_dev = RT_NULL;
38+
static rt_hwtimerval_t timer_val;
39+
40+
static rt_uint32_t get_timer_us(void)
41+
{
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 * 1000000 + timer_val.usec);
45+
}
46+
return 0;
47+
}
48+
#endif
49+
50+
static void perf_thread_sem1(void *parameter)
51+
{
52+
rt_uint32_t total_time = 0;
53+
rt_event_send(perf_thread_event, EVENT_FLAG);
54+
while (1)
55+
{
56+
rt_sem_take(perf_thread_sem, RT_WAITING_FOREVER);
57+
#ifdef USING_HWTIME_AS_TIME_REF
58+
use_time[thread_event_count].end_time = get_timer_us();
59+
use_time[thread_event_count].use_time = use_time[thread_event_count].end_time - use_time[thread_event_count].start_time;
60+
#else
61+
use_time[thread_event_count].end_time = rt_tick_get();
62+
use_time[thread_event_count].use_time = (use_time[thread_event_count].end_time - use_time[thread_event_count].start_time) / RT_TICK_PER_SECOND;
63+
use_time[thread_event_count].use_time += ((use_time[thread_event_count].end_time - use_time[thread_event_count].start_time) % RT_TICK_PER_SECOND) * (1000000u / RT_TICK_PER_SECOND);
64+
#endif
65+
total_time += use_time[thread_event_count].use_time;
66+
thread_event_count ++;
67+
if (thread_event_count >= PERF_COUNT)
68+
{
69+
LOG_I("Semaphore test completed: %d iterations, total time = %lu us, average = %lu us per semaphore",
70+
PERF_COUNT, total_time, total_time / PERF_COUNT);
71+
72+
rt_event_delete(perf_thread_event);
73+
rt_sem_delete(perf_thread_sem);
74+
return;
75+
}
76+
rt_event_send(perf_thread_event, EVENT_FLAG);
77+
}
78+
}
79+
80+
static void perf_thread_sem2(void *parameter)
81+
{
82+
rt_err_t ret = RT_EOK;
83+
rt_uint32_t recv = 0;
84+
while (1)
85+
{
86+
if (thread_event_count >= PERF_COUNT)
87+
{
88+
return;
89+
}
90+
ret= rt_event_recv(perf_thread_event, EVENT_FLAG,
91+
(RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR),
92+
RT_WAITING_FOREVER, &recv);
93+
if (ret != RT_EOK)
94+
{
95+
LOG_E("event recv error!");
96+
rt_event_delete(perf_thread_event);
97+
rt_sem_delete(perf_thread_sem);
98+
return;
99+
}
100+
#ifdef USING_HWTIME_AS_TIME_REF
101+
use_time[thread_event_count].start_time = get_timer_us();
102+
#else
103+
use_time[thread_event_count].start_time = rt_tick_get();
104+
#endif
105+
rt_sem_release(perf_thread_sem);
106+
}
107+
}
108+
109+
static void rt_perf_thread_sem(void)
110+
{
111+
rt_thread_t thread1 = RT_NULL;
112+
rt_thread_t thread2 = RT_NULL;
113+
114+
perf_thread_sem = rt_sem_create("perf_thread_sem", 0, RT_IPC_FLAG_FIFO);
115+
if (perf_thread_sem == RT_NULL)
116+
{
117+
LOG_E("perf_thread_sem create failed.");
118+
return;
119+
}
120+
perf_thread_event = rt_event_create("perf_thread_event", RT_IPC_FLAG_PRIO);
121+
thread1 = rt_thread_create("perf_thread_sem1", perf_thread_sem1, RT_NULL,
122+
THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
123+
if (thread1 == RT_NULL)
124+
{
125+
LOG_E("perf_thread_sem1 create failed.");
126+
return;
127+
}
128+
129+
thread2 = rt_thread_create("perf_thread_sem2", perf_thread_sem2, RT_NULL,
130+
THREAD_STACK_SIZE, THREAD_PRIORITY + 1, THREAD_TIMESLICE);
131+
if (thread2 == RT_NULL)
132+
{
133+
LOG_E("perf_thread_sem2 create failed.");
134+
return;
135+
}
136+
137+
rt_thread_startup(thread1);
138+
rt_thread_startup(thread2);
139+
}
140+
141+
static rt_err_t utest_tc_init(void)
142+
{
143+
#ifdef USING_HWTIME_AS_TIME_REF
144+
rt_hwtimerval_t timeout_s;
145+
int ret = RT_EOK;
146+
hw_dev = rt_device_find(UTEST_HWTIMER_DEV_NAME);
147+
if (hw_dev == RT_NULL)
148+
{
149+
ret = RT_ERROR;
150+
LOG_E("hwtimer sample run failed! can't find %s device!", UTEST_HWTIMER_DEV_NAME);
151+
return ret;
152+
}
153+
154+
ret = rt_device_open(hw_dev, RT_DEVICE_OFLAG_RDWR);
155+
if (ret != RT_EOK)
156+
{
157+
LOG_E("open %s device failed!", UTEST_HWTIMER_DEV_NAME);
158+
return ret;
159+
}
160+
161+
timeout_s.sec = 10; /* s */
162+
timeout_s.usec = 0; /* us */
163+
if (rt_device_write(hw_dev, 0, &timeout_s, sizeof(rt_hwtimerval_t)) != sizeof(rt_hwtimerval_t))
164+
{
165+
ret = RT_ERROR;
166+
LOG_E("set timeout value failed");
167+
return ret;
168+
}
169+
#endif
170+
171+
return RT_EOK;
172+
}
173+
174+
static rt_err_t utest_tc_cleanup(void)
175+
{
176+
#ifdef USING_HWTIME_AS_TIME_REF
177+
if (hw_dev) rt_device_close(hw_dev);
178+
#endif
179+
return RT_EOK;
180+
}
181+
182+
static void testcase(void)
183+
{
184+
UTEST_UNIT_RUN(rt_perf_thread_sem);
185+
}
186+
187+
UTEST_TC_EXPORT(testcase, "testcase.pref.semaphore", utest_tc_init, utest_tc_cleanup, 10);

0 commit comments

Comments
 (0)