mirror of
https://github.com/wolfcw/libfaketime.git
synced 2026-05-17 08:36:28 +03:00
Added FAKETIME_XRESET to smoothen run-time transition between 'x' modifier values (#198)
This commit is contained in:
35
README
35
README
@@ -376,6 +376,41 @@ LD_PRELOAD=/path/to/libfaketime.so.1 \
|
||||
touch -t 2002290123.45 /tmp/my-demo-file.tmp
|
||||
|
||||
|
||||
Changing the 'x' modifier during run-time
|
||||
-----------------------------------------
|
||||
|
||||
Using FAKETIME_TIMESTAMP_FILE allows for easily changing the FAKETIME setting
|
||||
while a program is running:
|
||||
|
||||
echo "+0 x1" > /tmp/my-faketime.rc
|
||||
LD_PRELOAD=libfaketime.so.1 FAKETIME_TIMESTAMP_FILE="/tmp/my-faketime.rc" \
|
||||
FAKETIME_NO_CACHE=1 ./some-program &
|
||||
sleep 10 ; echo "+0 x10" > /tmp/my-faketime.rc
|
||||
|
||||
Changing the speed of the wall clock time, i.e., using a different 'x' modifier
|
||||
during run-time, by default can lead to greater jumps that may confuse the
|
||||
program. For example, if the program has been running for 10 seconds on 'x1',
|
||||
and then the setting is changed to 'x10', the faked time will look to the
|
||||
program as if it has been running for more than 100 instead of just more than
|
||||
10 seconds.
|
||||
|
||||
By setting the environment variable FAKETIME_XRESET to any value, transitions
|
||||
between different 'x' modifier values will be significantly smoothed:
|
||||
|
||||
LD_PRELOAD=libfaketime.so.1 FAKETIME_TIMESTAMP_FILE="/tmp/my-faketime.rc" \
|
||||
FAKETIME_NO_CACHE=1 FAKETIME_XRESET=1 ./some-program &
|
||||
|
||||
Setting FAKETIME_XRESET ensures that wall clock time begins to run faster
|
||||
only after the 'x' modifier has been changed (when increasing it) and also
|
||||
ensures that the reported faked time does not jump back to past values
|
||||
(when decreasing it).
|
||||
|
||||
Please note that FAKETIME_XRESET internally works by resetting libfaketime's
|
||||
internal time-keeping data structures, which may have side effects on reported
|
||||
file timestamps. Using FAKETIME_XRESET should be considered experimental at
|
||||
the moment.
|
||||
|
||||
|
||||
4f) Faking the date and time system-wide
|
||||
----------------------------------------
|
||||
|
||||
|
||||
@@ -248,8 +248,12 @@ static int cache_duration = 10; /* cache fake time input for 10 seconds */
|
||||
*/
|
||||
#ifndef CLOCK_BOOTTIME
|
||||
static struct system_time_s ftpl_starttime = {{0, -1}, {0, -1}, {0, -1}};
|
||||
static struct system_time_s ftpl_timecache = {{0, -1}, {0, -1}, {0, -1}};
|
||||
static struct system_time_s ftpl_faketimecache = {{0, -1}, {0, -1}, {0, -1}};
|
||||
#else
|
||||
static struct system_time_s ftpl_starttime = {{0, -1}, {0, -1}, {0, -1}, {0, -1}};
|
||||
static struct system_time_s ftpl_timecache = {{0, -1}, {0, -1}, {0, -1}, {0, -1}};
|
||||
static struct system_time_s ftpl_faketimecache = {{0, -1}, {0, -1}, {0, -1}, {0, -1}};
|
||||
#endif
|
||||
|
||||
static char user_faked_time_fmt[BUFSIZ] = {0};
|
||||
@@ -1951,6 +1955,22 @@ parse_modifiers:
|
||||
{
|
||||
user_rate = atof(strchr(user_faked_time, 'x')+1);
|
||||
user_rate_set = true;
|
||||
if (NULL != getenv("FAKETIME_XRESET")) {
|
||||
if (ftpl_timecache.real.tv_nsec >= 0) {
|
||||
user_faked_time_timespec.tv_sec = ftpl_faketimecache.real.tv_sec;
|
||||
user_faked_time_timespec.tv_nsec = ftpl_faketimecache.real.tv_nsec;
|
||||
ftpl_starttime.real.tv_sec = ftpl_timecache.real.tv_sec;
|
||||
ftpl_starttime.real.tv_nsec = ftpl_timecache.real.tv_nsec;
|
||||
ftpl_starttime.mon.tv_sec = ftpl_timecache.mon.tv_sec;
|
||||
ftpl_starttime.mon.tv_nsec = ftpl_timecache.mon.tv_nsec;
|
||||
ftpl_starttime.mon_raw.tv_sec = ftpl_timecache.mon_raw.tv_sec;
|
||||
ftpl_starttime.mon_raw.tv_nsec = ftpl_timecache.mon_raw.tv_nsec;
|
||||
#ifdef CLOCK_BOOTTIME
|
||||
ftpl_starttime.boot.tv_sec = ftpl_timecache.boot.tv_sec;
|
||||
ftpl_starttime.boot.tv_nsec = ftpl_timecache.boot.tv_nsec;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (NULL != (tmp_time_fmt = strchr(user_faked_time, 'i')))
|
||||
{
|
||||
@@ -2363,6 +2383,11 @@ int fake_clock_gettime(clockid_t clk_id, struct timespec *tp)
|
||||
static time_t last_data_fetch = 0; /* not fetched previously at first call */
|
||||
static int cache_expired = 1; /* considered expired at first call */
|
||||
|
||||
/* create a copy of the timespec containing the real system time for clk_id */
|
||||
struct timespec tp_save;
|
||||
tp_save.tv_sec = tp->tv_sec;
|
||||
tp_save.tv_nsec = tp->tv_nsec;
|
||||
|
||||
if (dont_fake) return 0;
|
||||
/* Per process timers are only sped up or slowed down */
|
||||
if ((clk_id == CLOCK_PROCESS_CPUTIME_ID ) || (clk_id == CLOCK_THREAD_CPUTIME_ID))
|
||||
@@ -2595,6 +2620,39 @@ int fake_clock_gettime(clockid_t clk_id, struct timespec *tp)
|
||||
pthread_cleanup_pop(1);
|
||||
#endif
|
||||
save_time(tp);
|
||||
|
||||
/* Cache this most recent real and faked time we encountered */
|
||||
if (clk_id == CLOCK_REALTIME)
|
||||
{
|
||||
ftpl_timecache.real.tv_sec = tp_save.tv_sec;
|
||||
ftpl_timecache.real.tv_nsec = tp_save.tv_nsec;
|
||||
ftpl_faketimecache.real.tv_sec = tp->tv_sec;
|
||||
ftpl_faketimecache.real.tv_nsec = tp->tv_nsec;
|
||||
}
|
||||
else if (clk_id == CLOCK_MONOTONIC)
|
||||
{
|
||||
ftpl_timecache.mon.tv_sec = tp_save.tv_sec;
|
||||
ftpl_timecache.mon.tv_nsec = tp_save.tv_nsec;
|
||||
ftpl_faketimecache.mon.tv_sec = tp->tv_sec;
|
||||
ftpl_faketimecache.mon.tv_nsec = tp->tv_nsec;
|
||||
}
|
||||
else if (clk_id == CLOCK_MONOTONIC_RAW)
|
||||
{
|
||||
ftpl_timecache.mon_raw.tv_sec = tp_save.tv_sec;
|
||||
ftpl_timecache.mon_raw.tv_nsec = tp_save.tv_nsec;
|
||||
ftpl_faketimecache.mon_raw.tv_sec = tp->tv_sec;
|
||||
ftpl_faketimecache.mon_raw.tv_nsec = tp->tv_nsec;
|
||||
}
|
||||
#ifdef CLOCK_BOOTTIME
|
||||
else if (clk_id == CLOCK_BOOTTIME)
|
||||
{
|
||||
ftpl_timecache.boot.tv_sec = tp_save.tv_sec;
|
||||
ftpl_timecache.boot.tv_nsec = tp_save.tv_nsec;
|
||||
ftpl_faketimecache.boot.tv_sec = tp->tv_sec;
|
||||
ftpl_faketimecache.boot.tv_nsec = tp->tv_nsec;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user