Skip to content

Commit b2d4ad6

Browse files
hujun260xiaoxiang781216
authored andcommitted
testing/ostest: Add performance event time counter test
Integrate up_perf_gettime() test into ostest suite with comprehensive test coverage including monotonicity verification, interval statistics, and frequency validation. The test verifies performance event counter functionality across 5 independent test cases with proper error handling. Signed-off-by: hujun5 <hujun5@xiaomi.com>
1 parent eda1309 commit b2d4ad6

File tree

5 files changed

+253
-0
lines changed

5 files changed

+253
-0
lines changed

testing/ostest/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,10 @@ if(CONFIG_TESTING_OSTEST)
161161
list(APPEND SRCS hrtimer.c)
162162
endif()
163163

164+
if(CONFIG_ARCH_HAVE_PERF_EVENTS)
165+
list(APPEND SRCS perf_gettime.c)
166+
endif()
167+
164168
if(CONFIG_BUILD_FLAT)
165169
list(APPEND SRCS wdog.c spinlock.c)
166170
endif()

testing/ostest/Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,10 @@ CSRCS += hrtimer.c
166166
endif
167167
endif
168168

169+
ifeq ($(CONFIG_ARCH_HAVE_PERF_EVENTS),y)
170+
CSRCS += perf_gettime.c
171+
endif
172+
169173
ifeq ($(CONFIG_BUILD_FLAT),y)
170174
CSRCS += wdog.c spinlock.c
171175
endif

testing/ostest/ostest.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,12 @@ void smp_call_test(void);
290290

291291
void spinlock_test(void);
292292

293+
/* perf_gettime.c ***********************************************************/
294+
295+
#ifdef CONFIG_ARCH_HAVE_PERF_EVENTS
296+
void perf_gettime_test(void);
297+
#endif
298+
293299
/* APIs exported (conditionally) by the OS specifically for testing of
294300
* priority inheritance
295301
*/

testing/ostest/ostest_main.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,14 @@ static int user_main(int argc, char *argv[])
635635
check_test_memory_usage();
636636
#endif
637637

638+
#if defined(CONFIG_ARCH_PERF_EVENTS) && !defined(CONFIG_ARCH_PERF_EVENTS_USER_ACCESS)
639+
/* Verify performance event time counter */
640+
641+
printf("\nuser_main: performance event time counter test\n");
642+
perf_gettime_test();
643+
check_test_memory_usage();
644+
#endif
645+
638646
#if defined(CONFIG_HRTIMER) && defined(CONFIG_BUILD_FLAT)
639647
/* Verify hrtimer */
640648

testing/ostest/perf_gettime.c

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
/****************************************************************************
2+
* apps/testing/ostest/perf_gettime.c
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Licensed to the Apache Software Foundation (ASF) under one or more
7+
* contributor license agreements. See the NOTICE file distributed with
8+
* this work for additional information regarding copyright ownership. The
9+
* ASF licenses this file to you under the Apache License, Version 2.0 (the
10+
* "License"); you may not use this file except in compliance with the
11+
* License. You may obtain a copy of the License at
12+
*
13+
* http://www.apache.org/licenses/LICENSE-2.0
14+
*
15+
* Unless required by applicable law or agreed to in writing, software
16+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18+
* License for the specific language governing permissions and limitations
19+
* under the License.
20+
*
21+
****************************************************************************/
22+
23+
/****************************************************************************
24+
* Included Files
25+
****************************************************************************/
26+
27+
#include <nuttx/config.h>
28+
#include <nuttx/arch.h>
29+
30+
#include <assert.h>
31+
#include <stdio.h>
32+
#include <unistd.h>
33+
#include <stdlib.h>
34+
#include <time.h>
35+
#include <sys/types.h>
36+
37+
#include "ostest.h"
38+
39+
/****************************************************************************
40+
* Pre-processor Definitions
41+
****************************************************************************/
42+
43+
/* Performance event test parameters */
44+
45+
#define PERF_ITERATIONS 10
46+
#define SLEEP_INTERVAL_USEC 100000 /* 100ms */
47+
48+
/****************************************************************************
49+
* Private Data
50+
****************************************************************************/
51+
52+
#ifdef CONFIG_ARCH_PERF_EVENTS
53+
static clock_t g_prev_time = 0;
54+
static clock_t g_min_interval = ULONG_MAX;
55+
static clock_t g_max_interval = 0;
56+
static unsigned long g_total_interval = 0;
57+
static int g_iteration_count = 0;
58+
#endif
59+
60+
/****************************************************************************
61+
* Public Functions
62+
****************************************************************************/
63+
64+
/****************************************************************************
65+
* Name: perf_gettime_test
66+
*
67+
* Description:
68+
* Test performance event time counter: perf_gettime()
69+
*
70+
* This test verifies:
71+
* 1. perf_gettime() returns non-zero values
72+
* 2. Time values are monotonically increasing
73+
* 3. Multiple calls return consistent intervals
74+
* 4. Performance counter frequency is reasonable
75+
*
76+
****************************************************************************/
77+
78+
void perf_gettime_test(void)
79+
{
80+
#ifdef CONFIG_ARCH_PERF_EVENTS
81+
int i;
82+
clock_t curr_time;
83+
clock_t time_interval;
84+
unsigned long perf_freq;
85+
86+
printf("\nperf_gettime_test: Starting performance event test\n");
87+
88+
/* Test 1: Get initial time value */
89+
90+
printf("\nTest 1: Getting initial performance time value\n");
91+
g_prev_time = perf_gettime();
92+
printf("perf_gettime_test: Initial time = %lu\n",
93+
(unsigned long)g_prev_time);
94+
95+
/* We expect the counter to not be zero (unless just initialized) */
96+
97+
if (g_prev_time == 0)
98+
{
99+
printf("perf_gettime_test: WARNING - Initial time is zero\n");
100+
}
101+
102+
/* Test 2: Verify monotonically increasing time */
103+
104+
printf("\nTest 2: Verify monotonically increasing time values\n");
105+
g_total_interval = 0;
106+
g_min_interval = ULONG_MAX;
107+
g_max_interval = 0;
108+
g_iteration_count = 0;
109+
110+
for (i = 0; i < PERF_ITERATIONS; i++)
111+
{
112+
/* Sleep for a short interval */
113+
114+
usleep(SLEEP_INTERVAL_USEC);
115+
116+
/* Get new time value */
117+
118+
curr_time = perf_gettime();
119+
time_interval = curr_time - g_prev_time;
120+
121+
printf("perf_gettime_test [%d]: current=%lu, interval=%lu\n",
122+
i, (unsigned long)curr_time, (unsigned long)time_interval);
123+
124+
/* Verify time is monotonically increasing */
125+
126+
if (curr_time <= g_prev_time)
127+
{
128+
printf("perf_gettime_test: ERROR - Time not monotonically "
129+
"increasing at iteration %d\n", i);
130+
printf(" Previous time: %lu, Current time: %lu\n",
131+
(unsigned long)g_prev_time, (unsigned long)curr_time);
132+
ASSERT(false);
133+
}
134+
135+
/* Track intervals */
136+
137+
if (time_interval < g_min_interval)
138+
{
139+
g_min_interval = time_interval;
140+
}
141+
142+
if (time_interval > g_max_interval)
143+
{
144+
g_max_interval = time_interval;
145+
}
146+
147+
g_total_interval += time_interval;
148+
g_iteration_count++;
149+
150+
g_prev_time = curr_time;
151+
}
152+
153+
/* Test 3: Analyze time intervals */
154+
155+
printf("\nTest 3: Analyzing time intervals\n");
156+
157+
if (g_iteration_count > 0)
158+
{
159+
unsigned long avg_interval = g_total_interval / g_iteration_count;
160+
161+
printf("perf_gettime_test: Interval statistics:\n");
162+
printf(" Minimum interval: %lu\n", (unsigned long)g_min_interval);
163+
printf(" Maximum interval: %lu\n", (unsigned long)g_max_interval);
164+
printf(" Average interval: %lu\n", avg_interval);
165+
printf(" Total iterations: %d\n", g_iteration_count);
166+
167+
/* Verify that intervals are within reasonable bounds */
168+
169+
if (g_max_interval == 0 || g_min_interval == ULONG_MAX)
170+
{
171+
printf("perf_gettime_test: WARNING - \
172+
No time intervals recorded\n");
173+
}
174+
else
175+
{
176+
printf("perf_gettime_test: Time intervals look reasonable\n");
177+
}
178+
}
179+
180+
/* Test 4: Test perf_getfreq() if available */
181+
182+
printf("\nTest 4: Getting performance counter frequency\n");
183+
184+
perf_freq = perf_getfreq();
185+
printf("perf_gettime_test: Performance frequency = %lu Hz\n", perf_freq);
186+
187+
if (perf_freq == ULONG_MAX || perf_freq == 0)
188+
{
189+
printf("perf_gettime_test: WARNING - Performance frequency is " \
190+
"invalid or uninitialized\n");
191+
}
192+
else
193+
{
194+
printf("perf_gettime_test: Performance frequency is valid\n");
195+
}
196+
197+
/* Test 5: Multiple rapid calls */
198+
199+
printf("\nTest 5: Testing multiple rapid calls\n");
200+
201+
curr_time = perf_gettime();
202+
printf("perf_gettime_test: Rapid call 1: %lu\n", (unsigned long)curr_time);
203+
204+
/* Make several rapid calls */
205+
206+
for (i = 0; i < 5; i++)
207+
{
208+
clock_t t = perf_gettime();
209+
printf("perf_gettime_test: Rapid call %d: %lu\n", i + 2,
210+
(unsigned long)t);
211+
212+
/* Verify either monotonic increase or same value (on fast systems) */
213+
214+
if (t < curr_time)
215+
{
216+
printf("perf_gettime_test: ERROR - Time went backwards!\n");
217+
ASSERT(false);
218+
}
219+
220+
curr_time = t;
221+
}
222+
223+
printf("\nperf_gettime_test: All performance event tests PASSED\n");
224+
225+
#else /* CONFIG_ARCH_PERF_EVENTS */
226+
227+
printf("\nperf_gettime_test: Skipping test - "
228+
"CONFIG_ARCH_PERF_EVENTS not enabled\n");
229+
230+
#endif /* CONFIG_ARCH_PERF_EVENTS */
231+
}

0 commit comments

Comments
 (0)