wolfcw / libfaketime

libfaketime modifies the system time for a single application
https://github.com/wolfcw/libfaketime
GNU General Public License v2.0
2.71k stars 325 forks source link

[Questions] Realtime capabilities of libfaketime #394

Closed KUGA2 closed 2 years ago

KUGA2 commented 2 years ago

Hi,

we have a realtime system and stumbled upon this library. We are investigation possibilities to speed up the execution for simulation, when the CPU is faster then the embedded one.

This is not an issue but a few questions (I could not see any other contact form):

Thanks!

wolfcw commented 2 years ago

On Linux-like systems, libfaketime is typically LD_PRELOADed to individual processes, so intercepted system calls like clock_settime() are only handled locally within each process. However, for synchronisation of FAKETIME settings across processes, one can use environment variables, text files, or the timestamps of files.

libfaketime currently intercepts and handles system calls to

clock_get_time
clock_gettime
clock_nanosleep
epoll_pwait
epoll_wait
fstat
ftime
futimens
getentropy
getpid
getrandom
gettimeofday
lstat
nanosleep
poll
ppoll
pselect
pthread_cond_destroy
pthread_cond_init
pthread_cond_timedwait
select
sem_clockwait
sem_timedwait
sleep
stat
syscall
time
timerfd_gettime
timerfd_settime
timer_gettime
timer_settime
timespec_get
usleep
utime
utimensat
utimes

along with their respective parameters / types.

You can change the FAKETIME setting at run-time, typically in combination with disabling libfaketime's caching and using text files or file timestamps for FAKETIME specification. You can set frozen timestamps so time does not advance for the affected process, you can slow the progression of time down to a crawl, or you can let increment libfaketime the faked time automatically with each call to a time-related system call (which provides some sort of determinism and repeatability).

Given that libfaketime internally passes intercepted calls through to the original system calls (and then just fakes their return values), changes to FAKETIME settings have no effect while an original system call is waiting, e.g., for a long time-out. The actual effect will probably depend on how the application is implemented; if it uses short time-outs and, e.g., a loop for repeated calls until, e.g., a mutex becomes available, things should be fine, and otherwise it will probably wait for the originally specified time before picking up the new FAKETIME.

KUGA2 commented 2 years ago

Thank you!

Comeback on first question: Is the faketime timer affected by settime calls (e.g. ntp) of the host?

Maybe a little example:

Will the waiting sem_timedwait block (for 1min) for will it immediately return with timeout?

wolfcw commented 2 years ago

libfaketime passes intercepted system calls through to the original ones (and manipulates their result values afterwards).

So what you are asking really is whether the original system calls are affected by changes to the real system-wide time (at run-time, i.e., during a call to one of those system functions).

This probably depends on how the original system calls are implemented, e.g., as part of glibc and the operating system kernel. I can't give a one-size-fits-all answer to that and you probably have to try it out in your specific environment.

libfaketime pretty much just calculates an offset to add/subtract to/from the results of the original system calls based on the FAKETIME setting. It does not really care about the current system-wide time, and it does not implement any sleeping/waiting mechanisms on its own. It relies on the original system calls for that.

wolfcw commented 2 years ago

I assume your questions were answered sufficiently. Please feel free to re-open otherwise.