diff --git a/t/.gitignore b/t/.gitignore index 20217f0d0..e8f9c24b2 100644 --- a/t/.gitignore +++ b/t/.gitignore @@ -73,3 +73,4 @@ janus.c websocket.c test-stats ssllib.c +time-fudge-preload.so diff --git a/t/Makefile b/t/Makefile index 160f3a313..2bcd97794 100644 --- a/t/Makefile +++ b/t/Makefile @@ -101,7 +101,7 @@ TESTS+= test-amr-decode test-amr-encode endif endif -ADD_CLEAN= tests-preload.so $(TESTS) +ADD_CLEAN= tests-preload.so time-fudge-preload.so $(TESTS) ifeq ($(with_transcoding),yes) all-tests: unit-tests daemon-tests @@ -273,6 +273,9 @@ PRELOAD_LIBS += -ldl tests-preload.so: tests-preload.c $(CC) $(PRELOAD_CFLAGS) -o $@ -shared -fPIC $< $(LDFLAGS) $(PRELOAD_LIBS) +time-fudge-preload.so: time-fudge-preload.c + $(CC) $(PRELOAD_CFLAGS) -o $@ -shared -fPIC $< $(LDFLAGS) $(PRELOAD_LIBS) + spandsp_send_fax_pcm.c: spandsp_logging.h spandsp_send_fax_t38.c: spandsp_logging.h spandsp_recv_fax_t38.c: spandsp_logging.h diff --git a/t/time-fudge-preload.c b/t/time-fudge-preload.c new file mode 100644 index 000000000..1e24d5f66 --- /dev/null +++ b/t/time-fudge-preload.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include +#include + +static inline long long timeval_us(const struct timeval *t) { + return (long long) ((long long) t->tv_sec * 1000000LL) + t->tv_usec; +} +static inline void timeval_from_us(struct timeval *t, long long us) { + t->tv_sec = us/1000000LL; + t->tv_usec = us%1000000LL; +} +static inline long long timespec_ns(const struct timespec *t) { + return (long long) ((long long) t->tv_sec * 1000000000LL) + t->tv_nsec; +} +static inline void timespec_from_ns(struct timespec *t, long long ns) { + t->tv_sec = ns/1000000000LL; + t->tv_nsec = ns%1000000000LL; +} +static long long offset = 0; +int gettimeofday(struct timeval *restrict tv, void *restrict tz) { + __typeof__ (gettimeofday) *fn = dlsym(RTLD_NEXT, "gettimeofday"); + int ret = fn(tv, tz); + if (ret) + return ret; + long r = random(); + if (r < ((1L<<31) / 100)) { + // 1% chance + long long add = random() & 0xffff; + offset += add; + fprintf(stderr, "moving clock forward by %lli us\n", add); + } + long long tvs = timeval_us(tv); + tvs += offset; + timeval_from_us(tv, tvs); + return ret; +} +int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) { + __typeof__ (pthread_cond_timedwait) *fn = dlsym(RTLD_NEXT, "pthread_cond_timedwait"); + if (!abstime) + return fn(cond, mutex, abstime); + struct timespec tn; + long long ns = timespec_ns(abstime); + ns -= offset * 1000LL; + timespec_from_ns(&tn, ns); + return fn(cond, mutex, &tn); +}