mirror of
https://github.com/apache/nuttx-apps.git
synced 2026-08-01 20:29:00 +00:00
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>
This commit is contained in:
parent
eda1309745
commit
b2d4ad67b1
5 changed files with 253 additions and 0 deletions
|
|
@ -161,6 +161,10 @@ if(CONFIG_TESTING_OSTEST)
|
|||
list(APPEND SRCS hrtimer.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_ARCH_HAVE_PERF_EVENTS)
|
||||
list(APPEND SRCS perf_gettime.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_BUILD_FLAT)
|
||||
list(APPEND SRCS wdog.c spinlock.c)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -166,6 +166,10 @@ CSRCS += hrtimer.c
|
|||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_HAVE_PERF_EVENTS),y)
|
||||
CSRCS += perf_gettime.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_FLAT),y)
|
||||
CSRCS += wdog.c spinlock.c
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -290,6 +290,12 @@ void smp_call_test(void);
|
|||
|
||||
void spinlock_test(void);
|
||||
|
||||
/* perf_gettime.c ***********************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_HAVE_PERF_EVENTS
|
||||
void perf_gettime_test(void);
|
||||
#endif
|
||||
|
||||
/* APIs exported (conditionally) by the OS specifically for testing of
|
||||
* priority inheritance
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -635,6 +635,14 @@ static int user_main(int argc, char *argv[])
|
|||
check_test_memory_usage();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ARCH_PERF_EVENTS) && !defined(CONFIG_ARCH_PERF_EVENTS_USER_ACCESS)
|
||||
/* Verify performance event time counter */
|
||||
|
||||
printf("\nuser_main: performance event time counter test\n");
|
||||
perf_gettime_test();
|
||||
check_test_memory_usage();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_HRTIMER) && defined(CONFIG_BUILD_FLAT)
|
||||
/* Verify hrtimer */
|
||||
|
||||
|
|
|
|||
231
testing/ostest/perf_gettime.c
Normal file
231
testing/ostest/perf_gettime.c
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
/****************************************************************************
|
||||
* apps/testing/ostest/perf_gettime.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/arch.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "ostest.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Performance event test parameters */
|
||||
|
||||
#define PERF_ITERATIONS 10
|
||||
#define SLEEP_INTERVAL_USEC 100000 /* 100ms */
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_ARCH_PERF_EVENTS
|
||||
static clock_t g_prev_time = 0;
|
||||
static clock_t g_min_interval = ULONG_MAX;
|
||||
static clock_t g_max_interval = 0;
|
||||
static unsigned long g_total_interval = 0;
|
||||
static int g_iteration_count = 0;
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: perf_gettime_test
|
||||
*
|
||||
* Description:
|
||||
* Test performance event time counter: perf_gettime()
|
||||
*
|
||||
* This test verifies:
|
||||
* 1. perf_gettime() returns non-zero values
|
||||
* 2. Time values are monotonically increasing
|
||||
* 3. Multiple calls return consistent intervals
|
||||
* 4. Performance counter frequency is reasonable
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void perf_gettime_test(void)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_PERF_EVENTS
|
||||
int i;
|
||||
clock_t curr_time;
|
||||
clock_t time_interval;
|
||||
unsigned long perf_freq;
|
||||
|
||||
printf("\nperf_gettime_test: Starting performance event test\n");
|
||||
|
||||
/* Test 1: Get initial time value */
|
||||
|
||||
printf("\nTest 1: Getting initial performance time value\n");
|
||||
g_prev_time = perf_gettime();
|
||||
printf("perf_gettime_test: Initial time = %lu\n",
|
||||
(unsigned long)g_prev_time);
|
||||
|
||||
/* We expect the counter to not be zero (unless just initialized) */
|
||||
|
||||
if (g_prev_time == 0)
|
||||
{
|
||||
printf("perf_gettime_test: WARNING - Initial time is zero\n");
|
||||
}
|
||||
|
||||
/* Test 2: Verify monotonically increasing time */
|
||||
|
||||
printf("\nTest 2: Verify monotonically increasing time values\n");
|
||||
g_total_interval = 0;
|
||||
g_min_interval = ULONG_MAX;
|
||||
g_max_interval = 0;
|
||||
g_iteration_count = 0;
|
||||
|
||||
for (i = 0; i < PERF_ITERATIONS; i++)
|
||||
{
|
||||
/* Sleep for a short interval */
|
||||
|
||||
usleep(SLEEP_INTERVAL_USEC);
|
||||
|
||||
/* Get new time value */
|
||||
|
||||
curr_time = perf_gettime();
|
||||
time_interval = curr_time - g_prev_time;
|
||||
|
||||
printf("perf_gettime_test [%d]: current=%lu, interval=%lu\n",
|
||||
i, (unsigned long)curr_time, (unsigned long)time_interval);
|
||||
|
||||
/* Verify time is monotonically increasing */
|
||||
|
||||
if (curr_time <= g_prev_time)
|
||||
{
|
||||
printf("perf_gettime_test: ERROR - Time not monotonically "
|
||||
"increasing at iteration %d\n", i);
|
||||
printf(" Previous time: %lu, Current time: %lu\n",
|
||||
(unsigned long)g_prev_time, (unsigned long)curr_time);
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
/* Track intervals */
|
||||
|
||||
if (time_interval < g_min_interval)
|
||||
{
|
||||
g_min_interval = time_interval;
|
||||
}
|
||||
|
||||
if (time_interval > g_max_interval)
|
||||
{
|
||||
g_max_interval = time_interval;
|
||||
}
|
||||
|
||||
g_total_interval += time_interval;
|
||||
g_iteration_count++;
|
||||
|
||||
g_prev_time = curr_time;
|
||||
}
|
||||
|
||||
/* Test 3: Analyze time intervals */
|
||||
|
||||
printf("\nTest 3: Analyzing time intervals\n");
|
||||
|
||||
if (g_iteration_count > 0)
|
||||
{
|
||||
unsigned long avg_interval = g_total_interval / g_iteration_count;
|
||||
|
||||
printf("perf_gettime_test: Interval statistics:\n");
|
||||
printf(" Minimum interval: %lu\n", (unsigned long)g_min_interval);
|
||||
printf(" Maximum interval: %lu\n", (unsigned long)g_max_interval);
|
||||
printf(" Average interval: %lu\n", avg_interval);
|
||||
printf(" Total iterations: %d\n", g_iteration_count);
|
||||
|
||||
/* Verify that intervals are within reasonable bounds */
|
||||
|
||||
if (g_max_interval == 0 || g_min_interval == ULONG_MAX)
|
||||
{
|
||||
printf("perf_gettime_test: WARNING - \
|
||||
No time intervals recorded\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("perf_gettime_test: Time intervals look reasonable\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Test 4: Test perf_getfreq() if available */
|
||||
|
||||
printf("\nTest 4: Getting performance counter frequency\n");
|
||||
|
||||
perf_freq = perf_getfreq();
|
||||
printf("perf_gettime_test: Performance frequency = %lu Hz\n", perf_freq);
|
||||
|
||||
if (perf_freq == ULONG_MAX || perf_freq == 0)
|
||||
{
|
||||
printf("perf_gettime_test: WARNING - Performance frequency is " \
|
||||
"invalid or uninitialized\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("perf_gettime_test: Performance frequency is valid\n");
|
||||
}
|
||||
|
||||
/* Test 5: Multiple rapid calls */
|
||||
|
||||
printf("\nTest 5: Testing multiple rapid calls\n");
|
||||
|
||||
curr_time = perf_gettime();
|
||||
printf("perf_gettime_test: Rapid call 1: %lu\n", (unsigned long)curr_time);
|
||||
|
||||
/* Make several rapid calls */
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
clock_t t = perf_gettime();
|
||||
printf("perf_gettime_test: Rapid call %d: %lu\n", i + 2,
|
||||
(unsigned long)t);
|
||||
|
||||
/* Verify either monotonic increase or same value (on fast systems) */
|
||||
|
||||
if (t < curr_time)
|
||||
{
|
||||
printf("perf_gettime_test: ERROR - Time went backwards!\n");
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
curr_time = t;
|
||||
}
|
||||
|
||||
printf("\nperf_gettime_test: All performance event tests PASSED\n");
|
||||
|
||||
#else /* CONFIG_ARCH_PERF_EVENTS */
|
||||
|
||||
printf("\nperf_gettime_test: Skipping test - "
|
||||
"CONFIG_ARCH_PERF_EVENTS not enabled\n");
|
||||
|
||||
#endif /* CONFIG_ARCH_PERF_EVENTS */
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue