arch/sim: add simulated time ratio support

Add CONFIG_SIM_WALLTIME_RATIO Kconfig option and --sim-rt-ratio=
command-line argument to control the ratio of simulated time to
real time in percent. 100 means real-time (default), 200 means
simulated time advances twice as fast, 50 means half speed.

The implementation applies the ratio in host_gettime(), host_sleepuntil()
and host_settimer() so both SIM_WALLTIME_SLEEP and SIM_WALLTIME_SIGNAL
modes are supported.

This is inspired by the --rt-ratio feature in Zephyr's native_sim board.

Tested on sim:nsh with the following sleep test:

  $ echo -e "sleep 2\nexit" | time ./nuttx
  real    0m2.0xxs

  $ echo -e "sleep 2\nexit" | time ./nuttx --sim-rt-ratio=200
  real    0m1.0xxs

  $ echo -e "sleep 2\nexit" | time ./nuttx --sim-rt-ratio=50
  real    0m4.0xxs

Signed-off-by: Lingao Meng <menglingao@xiaomi.com>
This commit is contained in:
Lingao Meng 2026-04-24 19:09:26 +08:00 committed by Xiang Xiao
parent 0efe8c4f42
commit dfd735045c
4 changed files with 69 additions and 4 deletions

View file

@ -170,6 +170,16 @@ config SIM_WALLTIME_SIGNAL
endchoice
config SIM_WALLTIME_RATIO
int "Simulated time ratio in percent relative to real time"
default 100
range 1 100000
---help---
Set the ratio of simulated time to real time in percent.
100 means real-time (default). 200 means simulated time advances
twice as fast as real time. 50 means half speed.
This can also be overridden at runtime with --sim-rt-ratio=<percent>.
config SIM_LOOP_INTERVAL
int "loop interval in ms"
default 10

View file

@ -41,6 +41,13 @@
****************************************************************************/
static uint64_t g_start;
/* Ratio of simulated time to real time in percent. 100 means real-time
* (default). Values > 100 speed up simulated time; values < 100 slow it
* down. Overridable at runtime via --sim-rt-ratio=<percent>.
*/
static int g_time_ratio = CONFIG_SIM_WALLTIME_RATIO;
#ifdef __APPLE__
static dispatch_source_t g_timer;
@ -105,7 +112,14 @@ uint64_t host_gettime(bool rtc)
clock_gettime(rtc ? CLOCK_REALTIME : CLOCK_MONOTONIC, &tp);
current = 1000000000ull * tp.tv_sec + tp.tv_nsec;
return rtc ? current : current - g_start;
if (rtc)
{
return current;
}
/* Apply time ratio: simulated_time = real_elapsed * ratio / 100 */
return ((current - g_start) * g_time_ratio) / 100;
}
/****************************************************************************
@ -128,7 +142,31 @@ void host_sleepuntil(uint64_t nsec)
now = host_gettime(false);
if (nsec > now + 1000)
{
usleep((nsec - now) / 1000);
/* nsec is in simulated time; convert back to real duration to sleep */
usleep((((nsec - now) * 100) / g_time_ratio) / 1000);
}
}
/****************************************************************************
* Name: host_set_timeratio
*
* Description:
* Set the ratio of simulated time to real time in percent. 100 (default)
* means simulated time advances at the same rate as real time. Values
* greater than 100 speed up simulated time; values less than 100 slow it
* down.
*
* Input Parameters:
* ratio - The new time ratio in percent (must be > 0)
*
****************************************************************************/
void host_set_timeratio(int ratio)
{
if (ratio > 0)
{
g_time_ratio = ratio;
}
}
@ -148,9 +186,9 @@ void host_sleepuntil(uint64_t nsec)
int host_settimer(uint64_t nsec)
{
/* Convert to microseconds and set minimum timer to 1 microsecond. */
/* nsec is in simulated time; convert back to real absolute time. */
nsec += g_start;
nsec = ((nsec * 100) / g_time_ratio) + g_start;
#ifdef __APPLE__
dispatch_time_t start;

View file

@ -31,6 +31,7 @@
#include <setjmp.h>
#include <syslog.h>
#include <assert.h>
#include <string.h>
#include <nuttx/init.h>
#include <nuttx/arch.h>
@ -164,9 +165,24 @@ noprofile_function const char *__ubsan_default_options(void)
int main(int argc, char **argv, char **envp)
{
int i;
g_argc = argc;
g_argv = argv;
/* Parse simulator-specific options before handing control to NuttX.
* --sim-rt-ratio=<percent> Set simulated-to-real time ratio in percent
* (default 100). Values > 100 speed up simulated time; < 100 slow down.
*/
for (i = 1; i < argc; i++)
{
if (strncmp(argv[i], "--sim-rt-ratio=", 15) == 0)
{
host_set_timeratio(atoi(argv[i] + 15));
}
}
#ifdef CONFIG_ALLSYMS
allsyms_relocate();
#endif

View file

@ -245,6 +245,7 @@ int host_inittimer(void);
uint64_t host_gettime(bool rtc);
void host_sleep(uint64_t nsec);
void host_sleepuntil(uint64_t nsec);
void host_set_timeratio(int ratio);
int host_timerirq(void);
int host_settimer(uint64_t nsec);